ref: f79a97198558c19f004519c8523ea59fbcd8d78a
parent: f3e24e40bd024de6c8e4766b5d80089b3232ef1a
author: cinap_lenrek <cinap_lenrek@centraldogma>
date: Tue Dec 6 09:49:40 EST 2011
fix cdrom media change
--- a/sys/src/9/pc/sdiahci.c
+++ b/sys/src/9/pc/sdiahci.c
@@ -1473,24 +1473,22 @@
c = unit->dev->ctlr;
d = c->drive[unit->subno];
- r = 0;
-
- if(d->portm.feat & Datapi && d->drivechange){- r = scsionline(unit);
- if(r > 0)
- d->drivechange = 0;
- return r;
- }
-
ilock(d);
+ if(d->portm.feat & Datapi){+ d->drivechange = 0;
+ iunlock(d);
+ return scsionline(unit);
+ }
+ r = 0;
if(d->drivechange){- r = 2;
d->drivechange = 0;
- /* devsd resets this after online is called; why? */
- unit->sectors = d->sectors;
- unit->secsize = d->secsize;
+ r = 2;
}else if(d->state == Dready)
r = 1;
+ if(r){+ unit->sectors = d->sectors;
+ unit->secsize = d->secsize;
+ }
iunlock(d);
return r;
}
@@ -1707,7 +1705,6 @@
case SDretry:
continue;
}
-// print("%.2ux :: %.2ux :: %.4ux\n", r->cmd[0], r->status, d->port->task);r->rlen = d->portm.list->len;
return SDok;
}
--- a/sys/src/9/pc/sdide.c
+++ b/sys/src/9/pc/sdide.c
@@ -1188,7 +1188,7 @@
cmdport = ctlr->cmdport;
ctlport = ctlr->ctlport;
- as = ataready(cmdport, ctlport, drive->dev, Bsy|Drq, Drdy, 107*1000);
+ as = ataready(cmdport, ctlport, drive->dev, Bsy|Drq, 0, 107*1000);
/* used to test as&Chk as failure too, but some CD readers use that for media change */
if(as < 0)
return SDnostatus;
@@ -1242,12 +1242,12 @@
iunlock(ctlr);
if(drive->status & Chk){+ rv = SDcheck;
if(drive->pktdma){ print("atapktio: disabling dma\n");drive->dmactl = 0;
rv = SDretry;
- } else
- rv = SDcheck;
+ }
}
return rv;
}
@@ -1545,7 +1545,7 @@
ctlr = d->ctlr;
cmdport = ctlr->cmdport;
ctlport = ctlr->ctlport;
- if(ataready(cmdport, ctlport, d->dev, Bsy|Drq, d->pkt? 0: Drdy, 101*1000) < 0)
+ if(ataready(cmdport, ctlport, d->dev, Bsy|Drq, d->pkt ? 0 : Drdy, 101*1000) < 0)
return -1;
ilock(ctlr);
@@ -1902,7 +1902,6 @@
print("Inil%2.2uX+", ctlr->command);return;
}
-
if(status & Err)
drive->error = inb(cmdport+Error);
else switch(drive->command){@@ -1999,8 +1998,8 @@
switch(p->did<<16 | p->did){case 0x439c<<16 | 0x1002:
case 0x438c<<16 | 0x1002:
-print("hi, anothy\n");-print("%T: allowing bad ccru %.2ux for suspected ide controller\n", p->tbdf, p->ccru);+ print("%T: allowing bad ccru %.2ux for suspected ide controller\n",+ p->tbdf, p->ccru);
return 1;
default:
return 0;
@@ -2411,9 +2410,8 @@
if((drive->flags & Online) == 0){drive->flags |= Online;
atadrive(unit, drive, ctlr->cmdport, ctlr->ctlport, drive->dev);
+ ret = 2;
}
- unit->sectors = drive->sectors;
- unit->secsize = drive->secsize;
if(drive->feat & Datapi){ulong dma;
@@ -2421,6 +2419,9 @@
drive->dmactl = 0;
ret = scsionline(unit);
drive->dmactl = dma;
+ } else {+ unit->sectors = drive->sectors;
+ unit->secsize = drive->secsize;
}
return ret;
}
--- a/sys/src/9/port/sdscsi.c
+++ b/sys/src/9/port/sdscsi.c
@@ -214,7 +214,6 @@
ulong ss;
uvlong s;
- *secsize = 0;
u = r->data;
if(r->clen == 16){s = (uvlong)belong(u)<<32 | belong(u + 4);
@@ -223,24 +222,8 @@
s = belong(u);
ss = belong(u + 4);
}
- /*
- * Some ATAPI CD readers lie about the block size.
- * Since we don't read audio via this interface
- * it's okay to always fudge this.
- */
- if(ss == 2352)
- ss = 2048;
- /*
- * Devices with removable media may return 0 sectors
- * when they have empty media (e.g. sata dvd writers);
- * if so, keep the count zero.
- *
- * Read-capacity returns the LBA of the last sector,
- * therefore the number of sectors must be incremented.
- */
- if(s != 0)
- s++;
- *secsize = ss;
+ if(secsize)
+ *secsize = ss;
return s;
}
@@ -249,6 +232,8 @@
{SDreq *r;
uchar *p;
+ ulong ss;
+ uvlong s;
int ok, retries;
void (*cap)(SDreq*);
@@ -276,20 +261,51 @@
memset(r->cmd, 0, sizeof r->cmd);
cap(r);
- r->status = ~0;
switch(scsirio(r)){default:
+ /*
+ * ATAPI returns error and no sense information
+ * on media change / no media present.
+ * count as retries.
+ */
+ if(retries < 4)
+ continue;
break;
case 0:
- unit->sectors = capreply(r, &unit->secsize);
- if(unit->sectors == 0xffffffff && cap == cap10){+ s = capreply(r, &ss);
+ if(s == 0xffffffff && cap == cap10){cap = cap16;
continue;
}
- ok = 1;
+ if(s == 0xffffffffffffffffLL)
+ s = 0;
+
+ /*
+ * Some ATAPI CD readers lie about the block size.
+ * Since we don't read audio via this interface
+ * it's okay to always fudge this.
+ */
+ if(ss == 2352)
+ ss = 2048;
+
+ /*
+ * Devices with removable media may return 0 sectors
+ * when they have empty media (e.g. sata dvd writers);
+ * if so, keep the count zero.
+ *
+ * Read-capacity returns the LBA of the last sector,
+ * therefore the number of sectors must be incremented.
+ */
+ if(s != 0)
+ s++;
+
+ ok = (unit->sectors != s) ? 2 : 1;
+ unit->sectors = s;
+ unit->secsize = ss;
break;
case 1:
- ok = 1;
+ ok = (unit->sectors != 0) ? 2 : 1;
+ unit->sectors = 0;
break;
case 2:
continue;
@@ -298,6 +314,11 @@
}
free(p);
free(r);
+
+ /*
+ print("scsionline: %s: ok=%d retries=%d sectors=%llud secsize=%lud\n",+ unit->name, ok, retries, unit->sectors, unit->secsize);
+ */
if(ok)
return ok+retries;
--
⑨