fix support for shared IRQ's.
fix support for multiple HPT & Promise controllers. support mixed 33/66 devices on the Promise 66 controllers. fix the refcount stuff in the atapi drivers. misc cleanups.
This commit is contained in:
parent
ffc4c1858f
commit
e12f0fb097
@ -328,7 +328,8 @@ ata_pciattach(device_t dev)
|
||||
/* is this controller busmaster DMA capable ? */
|
||||
if (pci_get_progif(dev) & PCIP_STORAGE_IDE_MASTERDEV) {
|
||||
/* is busmastering support turned on ? */
|
||||
if ((pci_read_config(dev, PCI_COMMAND_STATUS_REG, 4) & 5) == 5) {
|
||||
if ((cmd & (PCIM_CMD_PORTEN | PCIM_CMD_BUSMASTEREN)) ==
|
||||
(PCIM_CMD_PORTEN | PCIM_CMD_BUSMASTEREN)) {
|
||||
/* is there a valid port range to connect to ? */
|
||||
if ((bmaddr_1 = pci_read_config(dev, 0x20, 4) & IOMASK))
|
||||
bmaddr_2 = bmaddr_1 + ATA_BM_OFFSET1;
|
||||
@ -355,12 +356,18 @@ ata_pciattach(device_t dev)
|
||||
pci_write_config(dev, 0x53,
|
||||
(pci_read_config(dev, 0x53, 1) & ~0x01) | 0x02, 1);
|
||||
break;
|
||||
case 0x4d38105a: /* Promise 66's need their clock changed */
|
||||
outb(bmaddr_1 + 0x11, inb(bmaddr_1 + 0x11) | 0x0a);
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case 0x4d33105a:
|
||||
case 0x4d38105a: /* Promise's need burst mode to be turned on */
|
||||
case 0x4d33105a: /* Promise's need burst mode to be turned on */
|
||||
outb(bmaddr_1 + 0x1f, inb(bmaddr_1 + 0x1f) | 0x01);
|
||||
break;
|
||||
|
||||
case 0x00041103: /* HPT366 turn of fast interrupt prediction */
|
||||
pci_write_config(dev, 0x51, (pci_read_config(dev, 0x51, 1) & ~0x80), 1);
|
||||
break;
|
||||
|
||||
case 0x05711106:
|
||||
case 0x74091022: /* VIA 82C586, 82C596, 82C686 & AMD 756 default setup */
|
||||
/* set prefetch, postwrite */
|
||||
@ -381,10 +388,17 @@ ata_pciattach(device_t dev)
|
||||
pci_write_config(dev, 0x60, DEV_BSIZE, 2);
|
||||
pci_write_config(dev, 0x68, DEV_BSIZE, 2);
|
||||
|
||||
/* prepare for ATA-66 on the 82C686 */
|
||||
if (ata_find_dev(dev, 0x06861106))
|
||||
/* set the chiptype to the hostchip ID, makes life easier */
|
||||
if (ata_find_dev(dev, 0x05861106))
|
||||
type = 0x05861106;
|
||||
if (ata_find_dev(dev, 0x05961106))
|
||||
type = 0x05961106;
|
||||
if (ata_find_dev(dev, 0x06861106)) {
|
||||
type = 0x06861106;
|
||||
/* prepare for ATA-66 on the 82C686 */
|
||||
pci_write_config(dev, 0x50,
|
||||
pci_read_config(dev, 0x50, 4) | 0x070f070f, 4);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@ -736,15 +750,40 @@ static void
|
||||
ataintr(void *data)
|
||||
{
|
||||
struct ata_softc *scp = (struct ata_softc *)data;
|
||||
u_int8_t dmastat;
|
||||
|
||||
/* check if this interrupt is for us (shared PCI interrupts) */
|
||||
/* if DMA active look at the dmastatus */
|
||||
if ((scp->flags & ATA_DMA_ACTIVE) &&
|
||||
!(ata_dmastatus(scp) & ATA_BMSTAT_INTERRUPT))
|
||||
/*
|
||||
* since we might share the IRQ with another device, and in some
|
||||
* case with our twin channel, we only want to process interrupts
|
||||
* that we know this channel generated.
|
||||
*/
|
||||
switch (scp->chiptype) {
|
||||
#if NPCI > 0
|
||||
case 0x00041103: /* HighPoint HPT366 */
|
||||
if (!((dmastat = ata_dmastatus(scp)) & ATA_BMSTAT_INTERRUPT))
|
||||
return;
|
||||
outb(scp->bmaddr + ATA_BMSTAT_PORT, dmastat | ATA_BMSTAT_INTERRUPT);
|
||||
break;
|
||||
|
||||
/* if drive is busy it didn't interrupt */
|
||||
if (((scp->status = inb(scp->ioaddr + ATA_STATUS))&ATA_S_BUSY)==ATA_S_BUSY)
|
||||
case 0x4d33105a: /* Promise 33's */
|
||||
case 0x4d38105a: /* Promise 66's */
|
||||
if (!(inl((pci_read_config(scp->dev, 0x20, 4) & IOMASK) + 0x1c) &
|
||||
((scp->unit) ? 0x00004000 : 0x00000400)))
|
||||
return;
|
||||
/* FALLTHROUGH */
|
||||
#endif
|
||||
default:
|
||||
if (scp->flags & ATA_DMA_ACTIVE) {
|
||||
if (!(dmastat = ata_dmastatus(scp)) & ATA_BMSTAT_INTERRUPT)
|
||||
return;
|
||||
else
|
||||
outb(scp->bmaddr+ATA_BMSTAT_PORT, dmastat|ATA_BMSTAT_INTERRUPT);
|
||||
}
|
||||
}
|
||||
DELAY(1);
|
||||
|
||||
/* get status, if drive is busy it didn't interrupt so return */
|
||||
if ((scp->status = inb(scp->ioaddr + ATA_STATUS)) & ATA_S_BUSY)
|
||||
return;
|
||||
|
||||
/* find & call the responsible driver to process this interrupt */
|
||||
@ -794,8 +833,12 @@ ataintr(void *data)
|
||||
void
|
||||
ata_start(struct ata_softc *scp)
|
||||
{
|
||||
#if NATADISK > 0
|
||||
struct ad_request *ad_request;
|
||||
#endif
|
||||
#if NATAPICD > 0 || NATAPIFD > 0 || NATAPIST > 0
|
||||
struct atapi_request *atapi_request;
|
||||
#endif
|
||||
|
||||
if (scp->active != ATA_IDLE)
|
||||
return;
|
||||
@ -1099,8 +1142,14 @@ active2str(int32_t active)
|
||||
switch (active) {
|
||||
case ATA_IDLE:
|
||||
return("ATA_IDLE");
|
||||
case ATA_IMMEDIATE:
|
||||
return("ATA_IMMEDIATE");
|
||||
case ATA_WAIT_INTR:
|
||||
return("ATA_WAIT_INTR");
|
||||
case ATA_WAIT_READY:
|
||||
return("ATA_WAIT_READY");
|
||||
case ATA_ACTIVE:
|
||||
return("ATA_ACTIVE");
|
||||
case ATA_ACTIVE_ATA:
|
||||
return("ATA_ACTIVE_ATA");
|
||||
case ATA_ACTIVE_ATAPI:
|
||||
|
@ -459,10 +459,10 @@ ad_interrupt(struct ad_request *request)
|
||||
|
||||
/* did any real errors happen ? */
|
||||
if ((adp->controller->status & ATA_S_ERROR) ||
|
||||
(request->flags & AR_F_DMA_USED && dma_stat != ATA_BMSTAT_INTERRUPT)) {
|
||||
((request->flags & AR_F_DMA_USED) && (dma_stat & ATA_BMSTAT_ERROR))) {
|
||||
oops:
|
||||
printf("ad%d: %s %s ERROR blk# %d", adp->lun,
|
||||
(adp->controller->error & ATA_E_ICRC) ? "UDMA CRC" : "HARD",
|
||||
(adp->controller->error & ATA_E_ICRC) ? "UDMA ICRC" : "HARD",
|
||||
(request->flags & AR_F_READ) ? "READ" : "WRITE",
|
||||
request->blockaddr + (request->donecount / DEV_BSIZE));
|
||||
|
||||
|
@ -255,40 +255,37 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
|
||||
/* we could set PIO mode timings, but we assume the BIOS did that */
|
||||
break;
|
||||
|
||||
case 0x05711106: /* VIA 82C571, 82C586, 82C596 & 82C686 */
|
||||
case 0x74091022: /* AMD 756 */
|
||||
/* UDMA modes on 82C686 */
|
||||
if (ata_find_dev(scp->dev, 0x06861106)) {
|
||||
if (udmamode >= 4) {
|
||||
error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
|
||||
ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY);
|
||||
if (bootverbose)
|
||||
ata_printf(scp, device,
|
||||
"%s setting up UDMA4 mode on VIA chip\n",
|
||||
(error) ? "failed" : "success");
|
||||
if (!error) {
|
||||
pci_write_config(scp->dev, 0x53 - devno, 0xe8, 1);
|
||||
scp->mode[ATA_DEV(device)] = ATA_UDMA4;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (udmamode >= 2) {
|
||||
error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
|
||||
ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
|
||||
if (bootverbose)
|
||||
ata_printf(scp, device,
|
||||
"%s setting up UDMA2 mode on VIA chip\n",
|
||||
(error) ? "failed" : "success");
|
||||
if (!error) {
|
||||
pci_write_config(scp->dev, 0x53 - devno, 0xea, 1);
|
||||
scp->mode[ATA_DEV(device)] = ATA_UDMA2;
|
||||
return;
|
||||
}
|
||||
case 0x06861106: /* VIA 82C686 */
|
||||
if (udmamode >= 4) {
|
||||
error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
|
||||
ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY);
|
||||
if (bootverbose)
|
||||
ata_printf(scp, device,
|
||||
"%s setting up UDMA4 mode on VIA chip\n",
|
||||
(error) ? "failed" : "success");
|
||||
if (!error) {
|
||||
pci_write_config(scp->dev, 0x53 - devno, 0xe8, 1);
|
||||
scp->mode[ATA_DEV(device)] = ATA_UDMA4;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (udmamode >= 2) {
|
||||
error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
|
||||
ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
|
||||
if (bootverbose)
|
||||
ata_printf(scp, device,
|
||||
"%s setting up UDMA2 mode on VIA chip\n",
|
||||
(error) ? "failed" : "success");
|
||||
if (!error) {
|
||||
pci_write_config(scp->dev, 0x53 - devno, 0xea, 1);
|
||||
scp->mode[ATA_DEV(device)] = ATA_UDMA2;
|
||||
return;
|
||||
}
|
||||
}
|
||||
goto via_generic;
|
||||
|
||||
/* UDMA4 mode on AMD 756 */
|
||||
if (udmamode >= 4 && scp->chiptype == 0x74091022) {
|
||||
case 0x74091022: /* AMD 756 */
|
||||
if (udmamode >= 4) {
|
||||
error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
|
||||
ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY);
|
||||
if (bootverbose)
|
||||
@ -301,11 +298,15 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case 0x05961106: /* VIA 82C596 */
|
||||
case 0x05861106: /* VIA 82C586 */
|
||||
|
||||
/* UDMA2 mode only on 82C586 > rev1, 82C596, AMD 756 */
|
||||
if ((udmamode >= 2 && ata_find_dev(scp->dev, 0x05861106) &&
|
||||
if ((udmamode >= 2 && scp->chiptype == 0x05861106 &&
|
||||
pci_read_config(scp->dev, 0x08, 1) >= 0x01) ||
|
||||
(udmamode >= 2 && ata_find_dev(scp->dev, 0x05961106)) ||
|
||||
(udmamode >= 2 && scp->chiptype == 0x05961106) ||
|
||||
(udmamode >= 2 && scp->chiptype == 0x74091022)) {
|
||||
error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
|
||||
ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
|
||||
@ -319,6 +320,10 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case 0x05711106: /* VIA 82C571 */
|
||||
via_generic:
|
||||
if (wdmamode >= 2 && apiomode >= 4) {
|
||||
error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
|
||||
ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
|
||||
@ -382,7 +387,6 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
|
||||
"%s setting up UDMA4 mode on Promise chip\n",
|
||||
(error) ? "failed" : "success");
|
||||
if (!error) {
|
||||
outb(scp->bmaddr+0x11, inl(scp->bmaddr+0x11) | scp->unit ? 8:2);
|
||||
promise_timing(scp, devno, ATA_UDMA4);
|
||||
scp->mode[ATA_DEV(device)] = ATA_UDMA4;
|
||||
return;
|
||||
@ -512,8 +516,16 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
|
||||
}
|
||||
}
|
||||
}
|
||||
error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
|
||||
ata_pio2mode(apiomode), ATA_C_F_SETXFER,ATA_WAIT_READY);
|
||||
if (bootverbose)
|
||||
ata_printf(scp, device, "using PIO mode set by BIOS\n");
|
||||
ata_printf(scp, device, "%s setting up PIO%d mode on generic chip\n",
|
||||
(error) ? "failed" : "success", apiomode < 0 ? 0 : apiomode);
|
||||
if (!error)
|
||||
scp->mode[ATA_DEV(device)] = ata_pio2mode(apiomode);
|
||||
else
|
||||
if (bootverbose)
|
||||
ata_printf(scp, device, "using PIO mode set by BIOS\n");
|
||||
}
|
||||
|
||||
int32_t
|
||||
@ -586,17 +598,55 @@ ata_dmastatus(struct ata_softc *scp)
|
||||
static void
|
||||
promise_timing(struct ata_softc *scp, int32_t devno, int32_t mode)
|
||||
{
|
||||
u_int32_t timing;
|
||||
switch (mode) {
|
||||
default:
|
||||
case ATA_PIO0: timing = 0x004ff329; break;
|
||||
case ATA_PIO1: timing = 0x004fec25; break;
|
||||
case ATA_PIO2: timing = 0x004fe823; break;
|
||||
case ATA_PIO3: timing = 0x004fe622; break;
|
||||
case ATA_PIO4: timing = 0x004fe421; break;
|
||||
case ATA_WDMA2: timing = 0x004367f3; break;
|
||||
case ATA_UDMA2: timing = 0x004127f3; break;
|
||||
case ATA_UDMA4: timing = 0x004127f3; break;
|
||||
u_int32_t timing = 0;
|
||||
struct promise_timing {
|
||||
u_int8_t pa:4;
|
||||
u_int8_t prefetch:1;
|
||||
u_int8_t iordy:1;
|
||||
u_int8_t errdy:1;
|
||||
u_int8_t syncin:1;
|
||||
u_int8_t pb:5;
|
||||
u_int8_t mb:3;
|
||||
u_int8_t mc:4;
|
||||
u_int8_t dmaw:1;
|
||||
u_int8_t dmar:1;
|
||||
u_int8_t iordyp:1;
|
||||
u_int8_t dmarqp:1;
|
||||
u_int8_t reserved:8;
|
||||
} *t = (struct promise_timing*)&timing;
|
||||
|
||||
t->iordy = 1; t->iordyp = 1;
|
||||
if (mode >= ATA_DMA) {
|
||||
t->prefetch = 1; t->errdy = 1; t->syncin = 1;
|
||||
}
|
||||
|
||||
switch (scp->chiptype) {
|
||||
case 0x4d33105a: /* Promise 33's */
|
||||
switch (mode) {
|
||||
default:
|
||||
case ATA_PIO0: t->pa = 9; t->pb = 19; t->mb = 7; t->mc = 15; break;
|
||||
case ATA_PIO1: t->pa = 5; t->pb = 12; t->mb = 7; t->mc = 15; break;
|
||||
case ATA_PIO2: t->pa = 3; t->pb = 8; t->mb = 7; t->mc = 15; break;
|
||||
case ATA_PIO3: t->pa = 2; t->pb = 6; t->mb = 7; t->mc = 15; break;
|
||||
case ATA_PIO4: t->pa = 1; t->pb = 4; t->mb = 7; t->mc = 15; break;
|
||||
case ATA_WDMA2: t->pa = 3; t->pb = 7; t->mb = 3; t->mc = 3; break;
|
||||
case ATA_UDMA2: t->pa = 3; t->pb = 7; t->mb = 1; t->mc = 1; break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x4d38105a: /* Promise 66's */
|
||||
switch (mode) {
|
||||
default:
|
||||
case ATA_PIO0: t->pa = 15; t->pb = 31; t->mb = 7; t->mc = 15; break;
|
||||
case ATA_PIO1: t->pa = 10; t->pb = 24; t->mb = 7; t->mc = 15; break;
|
||||
case ATA_PIO2: t->pa = 6; t->pb = 16; t->mb = 7; t->mc = 15; break;
|
||||
case ATA_PIO3: t->pa = 4; t->pb = 12; t->mb = 7; t->mc = 15; break;
|
||||
case ATA_PIO4: t->pa = 2; t->pb = 8; t->mb = 7; t->mc = 15; break;
|
||||
case ATA_WDMA2: t->pa = 6; t->pb = 14; t->mb = 6; t->mc = 6; break;
|
||||
case ATA_UDMA2: t->pa = 6; t->pb = 14; t->mb = 2; t->mc = 2; break;
|
||||
case ATA_UDMA4: t->pa = 3; t->pb = 7; t->mb = 1; t->mc = 1; break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
pci_write_config(scp->dev, 0x60 + (devno << 2), timing, 4);
|
||||
}
|
||||
@ -647,7 +697,7 @@ hpt366_timing(struct ata_softc *scp, int32_t devno, int32_t mode)
|
||||
default: timing = 0x0120d9d9;
|
||||
}
|
||||
}
|
||||
pci_write_config(scp->dev, 0x40 + (devno << 2) , timing, 4);
|
||||
pci_write_config(scp->dev, 0x40 + (devno << 2) , (timing & ~0x80000000), 4);
|
||||
}
|
||||
|
||||
#else /* NPCI > 0 */
|
||||
|
@ -285,7 +285,7 @@ atapi_interrupt(struct atapi_request *request)
|
||||
dma_stat = ata_dmadone(atp->controller);
|
||||
atp->flags &= ~ATAPI_F_DMA_USED;
|
||||
if ((atp->controller->status & (ATA_S_ERROR | ATA_S_DWF)) ||
|
||||
dma_stat != ATA_BMSTAT_INTERRUPT) {
|
||||
dma_stat & ATA_BMSTAT_ERROR) {
|
||||
request->result = inb(atp->controller->ioaddr + ATA_ERROR);
|
||||
}
|
||||
else {
|
||||
|
@ -69,7 +69,7 @@ static struct cdevsw acd_cdevsw = {
|
||||
/* maj */ 117,
|
||||
/* dump */ nodump,
|
||||
/* psize */ nopsize,
|
||||
/* flags */ D_DISK,
|
||||
/* flags */ D_DISK | D_TRACKCLOSE,
|
||||
/* bmaj */ 31
|
||||
};
|
||||
|
||||
@ -207,7 +207,6 @@ acd_init_lun(struct atapi_softc *atp, int32_t lun, struct devstat *stats)
|
||||
acd->lun = lun;
|
||||
acd->flags &= ~(F_WRITTEN|F_DISK_OPEN|F_TRACK_OPEN);
|
||||
acd->block_size = 2048;
|
||||
acd->refcnt = 0;
|
||||
acd->slot = -1;
|
||||
acd->changer_info = NULL;
|
||||
acd->atp->flags |= ATAPI_F_MEDIA_CHANGED;
|
||||
@ -458,7 +457,7 @@ acdopen(dev_t dev, int32_t flags, int32_t fmt, struct proc *p)
|
||||
cdp->flags |= F_WRITING;
|
||||
}
|
||||
|
||||
if (!cdp->refcnt) {
|
||||
if (!cdp->refcnt++) {
|
||||
acd_prevent_allow(cdp, 1);
|
||||
cdp->flags |= F_LOCKED;
|
||||
if (!(flags & O_NONBLOCK) && !(flags & FWRITE))
|
||||
@ -466,7 +465,6 @@ acdopen(dev_t dev, int32_t flags, int32_t fmt, struct proc *p)
|
||||
else
|
||||
atapi_test_ready(cdp->atp);
|
||||
}
|
||||
cdp->refcnt++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -475,10 +473,7 @@ acdclose(dev_t dev, int32_t flags, int32_t fmt, struct proc *p)
|
||||
{
|
||||
struct acd_softc *cdp = dev->si_drv1;
|
||||
|
||||
cdp->refcnt--;
|
||||
|
||||
/* are we the last open ?? */
|
||||
if (!cdp->refcnt)
|
||||
if (!--cdp->refcnt)
|
||||
acd_prevent_allow(cdp, 0);
|
||||
|
||||
cdp->flags &= ~(F_LOCKED | F_WRITING);
|
||||
@ -1396,8 +1391,6 @@ acd_report_key(struct acd_softc *cdp, struct dvd_authinfo *ai)
|
||||
int16_t length;
|
||||
int8_t ccb[16];
|
||||
|
||||
printf("dvd_report_key: format=0x%x\n", ai->format);
|
||||
|
||||
switch (ai->format) {
|
||||
case DVD_REPORT_AGID:
|
||||
case DVD_REPORT_ASF:
|
||||
@ -1488,8 +1481,6 @@ acd_send_key(struct acd_softc *cdp, struct dvd_authinfo *ai)
|
||||
int16_t length;
|
||||
int8_t ccb[16];
|
||||
|
||||
printf("dvd_send_key: format=0x%x\n", ai->format);
|
||||
|
||||
bzero(&d, sizeof(d));
|
||||
|
||||
switch (ai->format) {
|
||||
@ -1532,8 +1523,6 @@ acd_read_structure(struct acd_softc *cdp, struct dvd_struct *s)
|
||||
int32_t error = 0;
|
||||
int8_t ccb[16];
|
||||
|
||||
printf("dvd_read_structure: format=0x%x\n", s->format);
|
||||
|
||||
bzero(&d, sizeof(d));
|
||||
|
||||
switch(s->format) {
|
||||
|
@ -65,8 +65,8 @@ static struct cdevsw afd_cdevsw = {
|
||||
/* maj */ 118,
|
||||
/* dump */ nodump,
|
||||
/* psize */ nopsize,
|
||||
/* flags */ D_DISK,
|
||||
/* bmaj */ 32,
|
||||
/* flags */ D_DISK | D_TRACKCLOSE,
|
||||
/* bmaj */ 32
|
||||
};
|
||||
static struct cdevsw afddisk_cdevsw;
|
||||
|
||||
@ -215,7 +215,8 @@ afdopen(dev_t dev, int32_t flags, int32_t fmt, struct proc *p)
|
||||
|
||||
atapi_test_ready(fdp->atp);
|
||||
|
||||
afd_prevent_allow(fdp, 1);
|
||||
if (!fdp->refcnt++)
|
||||
afd_prevent_allow(fdp, 1);
|
||||
|
||||
if (afd_sense(fdp))
|
||||
printf("afd%d: sense media type failed\n", fdp->lun);
|
||||
@ -237,7 +238,8 @@ afdclose(dev_t dev, int32_t flags, int32_t fmt, struct proc *p)
|
||||
{
|
||||
struct afd_softc *fdp = dev->si_drv1;
|
||||
|
||||
afd_prevent_allow(fdp, 0);
|
||||
if (!--fdp->refcnt)
|
||||
afd_prevent_allow(fdp, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -248,12 +250,12 @@ afdioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p)
|
||||
|
||||
switch (cmd) {
|
||||
case CDIOCEJECT:
|
||||
if ((fdp->flags & F_OPEN) && fdp->refcnt)
|
||||
if (fdp->refcnt > 1)
|
||||
return EBUSY;
|
||||
return afd_eject(fdp, 0);
|
||||
|
||||
case CDIOCCLOSE:
|
||||
if ((fdp->flags & F_OPEN) && fdp->refcnt)
|
||||
if (fdp->refcnt > 1)
|
||||
return 0;
|
||||
return afd_eject(fdp, 1);
|
||||
|
||||
|
@ -73,9 +73,6 @@ struct afd_cappage {
|
||||
struct afd_softc {
|
||||
struct atapi_softc *atp; /* controller structure */
|
||||
int32_t lun; /* logical device unit */
|
||||
int32_t flags; /* device state flags */
|
||||
#define F_OPEN 0x0001 /* the device is opened */
|
||||
|
||||
int32_t refcnt; /* the number of raw opens */
|
||||
int32_t transfersize; /* max size of each transfer */
|
||||
struct buf_queue_head buf_queue; /* queue of i/o requests */
|
||||
|
@ -64,7 +64,7 @@ static struct cdevsw ast_cdevsw = {
|
||||
/* maj */ 119,
|
||||
/* dump */ nodump,
|
||||
/* psize */ nopsize,
|
||||
/* flags */ D_TAPE,
|
||||
/* flags */ D_TAPE | D_TRACKCLOSE,
|
||||
/* bmaj */ -1
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user