--- ./misc/readcd.c.orig	2000-07-20 11:18:45.000000000 -0500
+++ ./misc/readcd.c	2009-07-22 16:19:33.000000000 -0500
@@ -615,10 +615,7 @@
 	long	addr;
 	int	cnt;
 {
-	if(addr <= G0_MAXADDR)
-		return(write_g0(scgp, bp, addr, cnt));
-	else
-		return(write_g1(scgp, bp, addr, cnt));
+	return(write_g1(scgp, bp, addr, cnt));
 }
 
 EXPORT int
@@ -947,6 +944,9 @@
 	long	end;
 	int	msec;
 	int	start;
+#ifdef _AIX
+        extern  int     using_ide;
+#endif
 
 	if (is_suid)
 		comerrno(EX_BAD, "Not root. Will not write in suid mode\n");
@@ -1004,6 +1004,13 @@
 	if (gettimeofday(&starttime, (struct timezone *)0) < 0)
 		comerr("Cannot get start time\n");
 
+#ifdef _AIX
+	if (using_ide) {
+		while ((cnt * scgp->cap->c_bsize) > 65535) /* USHRT_MAX */
+			cnt = cnt/2;
+	}
+#endif
+
 	for(;addr < end; addr += cnt) {
 
 		if ((addr + cnt) > end)
--- ./libscg/scsi-aix.c.orig	2000-07-01 05:22:50.000000000 -0500
+++ ./libscg/scsi-aix.c	2006-03-31 14:30:52.000000000 -0600
@@ -34,6 +34,15 @@
  */
 
 #include <sys/scdisk.h>
+#include <sys/ide.h>
+
+/*
+ * The scsi_inquiry struct in <sys/scsi_buf.h> clashes
+ * with the one in "scg/scsireg.h".
+ */
+#define scsi_inquiry _scsi_inquiry
+#include <sys/scsi_buf.h>
+#undef scsi_inquiry
 
 /*
  *	Warning: you may change this source, but if you do that
@@ -59,6 +68,9 @@
 LOCAL	int	do_scsi_cmd	__PR((SCSI *scgp, int f, struct scg_cmd *sp));
 LOCAL	int	do_scsi_sense	__PR((SCSI *scgp, int f, struct scg_cmd *sp));
 
+/*GLOBAL*/ enum { unknown, dkiocmd, dkpassthru, idepassthru } using = unknown;
+/*GLOBAL*/ int  using_ide = 0;
+
 /*
  * Return version information for the low level SCSI transport code.
  * This has been introduced to make it easier to trace down problems
@@ -303,6 +315,154 @@
 	return (ioctl(f, SCIORESET, IDLUN(scgp->target, scgp->lun)));
 }
 
+LOCAL void
+sciocmd_to_scpassthru(req, pthru_req, sp)
+	struct sc_iocmd	   *req;
+	struct sc_passthru *pthru_req;
+	struct scg_cmd     *sp;
+{
+  fillbytes(pthru_req, sizeof(*pthru_req), '\0');
+
+  pthru_req->version = SCSI_VERSION_1;
+  pthru_req->status_validity = req->status_validity;
+  pthru_req->scsi_bus_status = req->scsi_bus_status;
+  pthru_req->adapter_status = req->adapter_status;
+  pthru_req->adap_q_status = req->adap_q_status;
+  pthru_req->q_tag_msg = req->q_tag_msg;
+  pthru_req->flags = req->flags;
+  pthru_req->devflags = SC_QUIESCE_IO;
+  pthru_req->q_flags = req->q_flags;
+  pthru_req->command_length = req->command_length;
+  pthru_req->autosense_length = 0;
+  pthru_req->timeout_value = req->timeout_value;
+  pthru_req->data_length = (unsigned long long)req->data_length;
+  pthru_req->scsi_id = 0;
+  pthru_req->lun_id = req->lun;
+  pthru_req->buffer = req->buffer;
+  pthru_req->autosense_buffer_ptr = NULL;
+  movebytes(&sp->cdb, pthru_req->scsi_cdb, 12);
+}
+
+LOCAL void
+scpassthru_to_sciocmd(pthru_req, req)
+	struct sc_passthru *pthru_req;
+	struct sc_iocmd	   *req;
+{
+  req->data_length = pthru_req->data_length;
+  req->buffer = pthru_req->buffer;
+  req->timeout_value = pthru_req->timeout_value;
+  req->status_validity = pthru_req->status_validity;
+  req->scsi_bus_status = pthru_req->scsi_bus_status;
+  req->adapter_status = pthru_req->adapter_status;
+  req->adap_q_status = pthru_req->adap_q_status;
+  req->q_tag_msg = pthru_req->q_tag_msg;
+  req->flags = pthru_req->flags;
+}
+
+LOCAL int
+sciocmd_to_idepassthru(req, ide_req, sp)
+	struct sc_iocmd		  *req;
+	struct ide_atapi_passthru *ide_req;
+	struct scg_cmd		  *sp;
+{
+  fillbytes(ide_req, sizeof(*ide_req), '\0');
+
+  if ( sp->size > 65535) {  /* Too large for IDE */
+      sp->ux_errno = errno = EINVAL;
+      return(-1);
+  } else {
+      ide_req->buffsize = (ushort) sp->size;
+  }
+
+  if (sp->flags & SCG_RECV_DATA) {
+      ide_req->flags |= ATA_LBA_MODE | IDE_PASSTHRU_READ;
+  } else if (sp->size > 0) {
+      ide_req->flags |= ATA_LBA_MODE;
+  }
+
+  if (sp->size > 0) {
+      ide_req->data_ptr = sp->addr;
+  } else {
+      ide_req->data_ptr = NULL;
+  }
+  ide_req->timeout_value = (uint) sp->timeout;
+
+  /* IDE cmd length is 12 */
+  ide_req->atapi_cmd.length = 12;
+  movebytes(&sp->cdb, &(ide_req->atapi_cmd.packet), 12);
+
+  return 0;
+}
+
+LOCAL int
+do_ioctl(f, req, sp)
+	int		 f;
+	struct sc_iocmd *req;
+	struct scg_cmd  *sp;
+{
+  int                       dkiocmd_ret, dkiocmd_errno, ret;
+  struct sc_passthru        pthru_req;
+  struct ide_atapi_passthru ide_req;
+
+  if (using == unknown)
+    {
+      /* Try with DKIOCMD first. */
+      if ((dkiocmd_ret = ioctl(f, DKIOCMD, req)) > -1)
+        {
+          using = dkiocmd;
+          return dkiocmd_ret;
+        }
+      else
+        {
+          dkiocmd_errno = geterrno();
+        }
+
+      /* Try DKPASSTHRU second. */
+      sciocmd_to_scpassthru(req, &pthru_req, sp);
+      if ((ret = ioctl(f, DK_PASSTHRU, &pthru_req)) > -1)
+        {
+          using = dkpassthru;
+          scpassthru_to_sciocmd(&pthru_req, req);
+          return ret;
+        }
+
+      /* Last try IDEPASSTHRU */
+      if ( (sciocmd_to_idepassthru(req, &ide_req, sp) > -1) &&
+           ((ret = ioctl(f, IDEPASSTHRU, &ide_req)) > -1))
+        {
+          using = idepassthru;
+          using_ide = 1;
+          return ret;
+        }
+
+      /* Everything failed. */
+      errno = dkiocmd_errno;
+      return dkiocmd_ret; 
+    }
+  else if (using == dkiocmd)
+    {
+      return ioctl(f, DKIOCMD, req);
+    }
+  else if (using == dkpassthru)
+    {
+      sciocmd_to_scpassthru(req, &pthru_req, sp);
+      ret = ioctl(f, DK_PASSTHRU, &pthru_req);
+      scpassthru_to_sciocmd(&pthru_req, req);
+      return ret;
+    }
+  else if (using == idepassthru)
+    {  
+      if (sciocmd_to_idepassthru(req, &ide_req, sp) < 0)
+        ret = -1;
+      else
+        ret = ioctl(f, IDEPASSTHRU, &ide_req);
+
+      return ret;
+    }
+  else /* Shouldn't get here. */
+    return (-1);
+}
+
 LOCAL int
 do_scsi_cmd(scgp, f, sp)
 	SCSI		*scgp;
@@ -330,7 +490,7 @@
 
 	movebytes(&sp->cdb, req.scsi_cdb, 12);
 	errno = 0;
-	ret = ioctl(f, DKIOCMD, &req);
+	ret = do_ioctl(f, &req, sp);
 
 	if (scgp->debug) {
 		printf("ret: %d errno: %d (%s)\n", ret, errno, errmsgstr(errno));
