ZIP drives should now be working, I'm not sure about LS120 drives,
reports on those most welcome! Fixed problems: Hang on probe on "fantom" devices. The probe now use a timeout to avoid hangs if no interrupt is recevied. There has also been more general code clenaups, and some reorgs.
This commit is contained in:
parent
65b8ae0944
commit
b16da6db45
@ -25,7 +25,7 @@
|
|||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: ata-all.c,v 1.2 1999/03/03 21:10:29 sos Exp $
|
* $Id: ata-all.c,v 1.3 1999/03/05 09:43:30 sos Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ata.h"
|
#include "ata.h"
|
||||||
@ -271,6 +271,7 @@ ata_probe(int32_t ioaddr, int32_t altioaddr, int32_t *unit)
|
|||||||
scp->unit = lun;
|
scp->unit = lun;
|
||||||
scp->ioaddr = ioaddr;
|
scp->ioaddr = ioaddr;
|
||||||
scp->altioaddr = altioaddr;
|
scp->altioaddr = altioaddr;
|
||||||
|
scp->active = ATA_IDLE;
|
||||||
|
|
||||||
#ifdef ATA_DEBUG
|
#ifdef ATA_DEBUG
|
||||||
printf("ata%d: iobase=0x%04x altiobase=0x%04x\n",
|
printf("ata%d: iobase=0x%04x altiobase=0x%04x\n",
|
||||||
@ -419,29 +420,31 @@ ataintr(int32_t unit)
|
|||||||
#if NATADISK > 0
|
#if NATADISK > 0
|
||||||
case ATA_ACTIVE_ATA:
|
case ATA_ACTIVE_ATA:
|
||||||
if ((ata_request = bufq_first(&scp->ata_queue)))
|
if ((ata_request = bufq_first(&scp->ata_queue)))
|
||||||
ad_interrupt(ata_request);
|
if (ad_interrupt(ata_request) == ATA_OP_CONTINUES)
|
||||||
|
return;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
case ATA_ACTIVE_ATAPI:
|
case ATA_ACTIVE_ATAPI:
|
||||||
if ((atapi_request = TAILQ_FIRST(&scp->atapi_queue)))
|
if ((atapi_request = TAILQ_FIRST(&scp->atapi_queue)))
|
||||||
atapi_interrupt(atapi_request);
|
if (atapi_interrupt(atapi_request) == ATA_OP_CONTINUES)
|
||||||
|
return;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ATA_WAIT_INTR:
|
case ATA_WAIT_INTR:
|
||||||
wakeup((caddr_t)scp);
|
wakeup((caddr_t)scp);
|
||||||
scp->active = ATA_IDLE;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ATA_IGNORE_INTR:
|
case ATA_IGNORE_INTR:
|
||||||
scp->active = ATA_IDLE;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
case ATA_IDLE:
|
case ATA_IDLE:
|
||||||
if (intcount++ < 5)
|
if (intcount++ < 5)
|
||||||
printf("ata%d: unwanted interrupt\n", unit);
|
printf("ata%d: unwanted interrupt\n", unit);
|
||||||
break;
|
return;
|
||||||
}
|
}
|
||||||
|
scp->active = ATA_IDLE;
|
||||||
|
ata_start(scp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -481,6 +484,7 @@ ata_wait(struct ata_softc *scp, u_int8_t mask)
|
|||||||
status = inb(scp->ioaddr + ATA_STATUS);
|
status = inb(scp->ioaddr + ATA_STATUS);
|
||||||
if ((status == 0xff) && (scp->flags & ATA_F_SLAVE_ONLY)) {
|
if ((status == 0xff) && (scp->flags & ATA_F_SLAVE_ONLY)) {
|
||||||
outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | ATA_SLAVE);
|
outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | ATA_SLAVE);
|
||||||
|
DELAY(1);
|
||||||
status = inb(scp->ioaddr + ATA_STATUS);
|
status = inb(scp->ioaddr + ATA_STATUS);
|
||||||
}
|
}
|
||||||
if (status == 0xff)
|
if (status == 0xff)
|
||||||
@ -505,24 +509,30 @@ ata_command(struct ata_softc *scp, int32_t device, u_int32_t command,
|
|||||||
u_int32_t cylinder, u_int32_t head, u_int32_t sector,
|
u_int32_t cylinder, u_int32_t head, u_int32_t sector,
|
||||||
u_int32_t count, int32_t flags)
|
u_int32_t count, int32_t flags)
|
||||||
{
|
{
|
||||||
/* ready to issue command ? */
|
/* ready to issue command ? */
|
||||||
while (ata_wait(scp, 0) < 0) {
|
if (ata_wait(scp, 0) < 0) {
|
||||||
printf("ad_transfer: timeout waiting to give command");
|
printf("ata_command: timeout waiting to give command");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | device | head);
|
||||||
outb(scp->ioaddr + ATA_PRECOMP, 0); /* no precompensation */
|
outb(scp->ioaddr + ATA_PRECOMP, 0); /* no precompensation */
|
||||||
outb(scp->ioaddr + ATA_CYL_LSB, cylinder);
|
outb(scp->ioaddr + ATA_CYL_LSB, cylinder);
|
||||||
outb(scp->ioaddr + ATA_CYL_MSB, cylinder >> 8);
|
outb(scp->ioaddr + ATA_CYL_MSB, cylinder >> 8);
|
||||||
outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | device | head);
|
|
||||||
outb(scp->ioaddr + ATA_SECTOR, sector);
|
outb(scp->ioaddr + ATA_SECTOR, sector);
|
||||||
outb(scp->ioaddr + ATA_COUNT, count);
|
outb(scp->ioaddr + ATA_COUNT, count);
|
||||||
|
|
||||||
|
if (scp->active && flags != ATA_IMMEDIATE)
|
||||||
|
printf("DANGER active=%d\n", scp->active);
|
||||||
|
|
||||||
switch (flags) {
|
switch (flags) {
|
||||||
case ATA_WAIT_INTR:
|
case ATA_WAIT_INTR:
|
||||||
scp->active = ATA_WAIT_INTR;
|
scp->active = ATA_WAIT_INTR;
|
||||||
outb(scp->ioaddr + ATA_CMD, command);
|
outb(scp->ioaddr + ATA_CMD, command);
|
||||||
tsleep((caddr_t)scp, PRIBIO, "atacmd", 0);
|
if (tsleep((caddr_t)scp, PRIBIO, "atacmd", 500)) {
|
||||||
|
printf("ata_command: timeout waiting for interrupt");
|
||||||
|
scp->active = ATA_IDLE;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ATA_IGNORE_INTR:
|
case ATA_IGNORE_INTR:
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: ata-all.h,v 1.2 1999/03/03 21:10:29 sos Exp $
|
* $Id: ata-all.h,v 1.3 1999/03/05 09:43:30 sos Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* ATA register defines */
|
/* ATA register defines */
|
||||||
@ -72,6 +72,8 @@
|
|||||||
#define ATA_MASTER 0x00
|
#define ATA_MASTER 0x00
|
||||||
#define ATA_SLAVE 0x10
|
#define ATA_SLAVE 0x10
|
||||||
#define ATA_IOSIZE 0x08
|
#define ATA_IOSIZE 0x08
|
||||||
|
#define ATA_OP_FINISHED 0x00
|
||||||
|
#define ATA_OP_CONTINUES 0x01
|
||||||
|
|
||||||
/* Devices types */
|
/* Devices types */
|
||||||
#define ATA_ATA_MASTER 0x01
|
#define ATA_ATA_MASTER 0x01
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: ata-disk.c,v 1.2 1999/03/03 21:10:29 sos Exp $
|
* $Id: ata-disk.c,v 1.3 1999/03/05 09:43:30 sos Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ata.h"
|
#include "ata.h"
|
||||||
@ -80,7 +80,7 @@ static struct cdevsw ad_cdevsw = {
|
|||||||
|
|
||||||
/* prototypes */
|
/* prototypes */
|
||||||
static void ad_attach(void *);
|
static void ad_attach(void *);
|
||||||
static int32_t ata_get_param(struct ad_softc *);
|
static int32_t ad_getparam(struct ad_softc *);
|
||||||
static void ad_strategy(struct buf *);
|
static void ad_strategy(struct buf *);
|
||||||
static void ad_start(struct ad_softc *);
|
static void ad_start(struct ad_softc *);
|
||||||
static void ad_sleep(struct ad_softc *, int8_t *);
|
static void ad_sleep(struct ad_softc *, int8_t *);
|
||||||
@ -119,7 +119,7 @@ ad_attach(void *notused)
|
|||||||
adp->controller = atadevices[ctlr];
|
adp->controller = atadevices[ctlr];
|
||||||
adp->unit = (dev == 0) ? ATA_MASTER : ATA_SLAVE;
|
adp->unit = (dev == 0) ? ATA_MASTER : ATA_SLAVE;
|
||||||
adp->lun = adnlun;
|
adp->lun = adnlun;
|
||||||
if (ata_get_param(adp)) {
|
if (ad_getparam(adp)) {
|
||||||
free(adp, M_DEVBUF);
|
free(adp, M_DEVBUF);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -136,6 +136,7 @@ ad_attach(void *notused)
|
|||||||
/* support multiple sectors / interrupt ? */
|
/* support multiple sectors / interrupt ? */
|
||||||
adp->transfersize = DEV_BSIZE;
|
adp->transfersize = DEV_BSIZE;
|
||||||
secsperint = min(adp->ata_parm->nsecperint, 16);
|
secsperint = min(adp->ata_parm->nsecperint, 16);
|
||||||
|
|
||||||
if (!ata_command(adp->controller, adp->unit, ATA_C_SET_MULTI,
|
if (!ata_command(adp->controller, adp->unit, ATA_C_SET_MULTI,
|
||||||
0, 0, 0, secsperint, ATA_WAIT_INTR) &&
|
0, 0, 0, secsperint, ATA_WAIT_INTR) &&
|
||||||
ata_wait(adp->controller, ATA_S_DRDY) >= 0)
|
ata_wait(adp->controller, ATA_S_DRDY) >= 0)
|
||||||
@ -187,7 +188,7 @@ ad_attach(void *notused)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int32_t
|
static int32_t
|
||||||
ata_get_param(struct ad_softc *adp)
|
ad_getparam(struct ad_softc *adp)
|
||||||
{
|
{
|
||||||
struct ata_params *ata_parm;
|
struct ata_params *ata_parm;
|
||||||
int8_t buffer[DEV_BSIZE];
|
int8_t buffer[DEV_BSIZE];
|
||||||
@ -365,10 +366,10 @@ ad_start(struct ad_softc *adp)
|
|||||||
#ifdef AD_DEBUG
|
#ifdef AD_DEBUG
|
||||||
printf("ad_start:\n");
|
printf("ad_start:\n");
|
||||||
#endif
|
#endif
|
||||||
/* newer called when adp->active != 0 SOS */
|
if (adp->active) {
|
||||||
if (adp->active)
|
printf("ad_start: should newer be called when active\n"); /* SOS */
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
if (!(bp = bufq_first(&adp->queue)))
|
if (!(bp = bufq_first(&adp->queue)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -411,7 +412,6 @@ ad_transfer(struct buf *bp)
|
|||||||
if (count > 255) /* SOS */
|
if (count > 255) /* SOS */
|
||||||
printf("ad_transfer: count=%d\n", count);
|
printf("ad_transfer: count=%d\n", count);
|
||||||
|
|
||||||
|
|
||||||
/* setup transfer length if multible sector access present */
|
/* setup transfer length if multible sector access present */
|
||||||
adp->currentsize = min(adp->bytecount, adp->transfersize);
|
adp->currentsize = min(adp->bytecount, adp->transfersize);
|
||||||
if (adp->currentsize > DEV_BSIZE)
|
if (adp->currentsize > DEV_BSIZE)
|
||||||
@ -419,12 +419,6 @@ ad_transfer(struct buf *bp)
|
|||||||
else
|
else
|
||||||
command = (bp->b_flags&B_READ) ? ATA_C_READ : ATA_C_WRITE;
|
command = (bp->b_flags&B_READ) ? ATA_C_READ : ATA_C_WRITE;
|
||||||
|
|
||||||
/* ready to issue command ? */
|
|
||||||
while (ata_wait(adp->controller, 0) < 0) {
|
|
||||||
printf("ad_transfer: timeout waiting to give command");
|
|
||||||
/*ata_unwedge(adp->controller); SOS */
|
|
||||||
}
|
|
||||||
|
|
||||||
ata_command(adp->controller, adp->unit, command, cylinder, head,
|
ata_command(adp->controller, adp->unit, command, cylinder, head,
|
||||||
sector + 1, count, ATA_IMMEDIATE);
|
sector + 1, count, ATA_IMMEDIATE);
|
||||||
}
|
}
|
||||||
@ -461,7 +455,7 @@ ad_transfer(struct buf *bp)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
int32_t
|
||||||
ad_interrupt(struct buf *bp)
|
ad_interrupt(struct buf *bp)
|
||||||
{
|
{
|
||||||
struct ad_softc *adp = bp->b_driver1;
|
struct ad_softc *adp = bp->b_driver1;
|
||||||
@ -525,7 +519,7 @@ oops:
|
|||||||
#endif
|
#endif
|
||||||
if (adp->bytecount > 0) {
|
if (adp->bytecount > 0) {
|
||||||
ad_transfer(bp); /* MESSY!! only needed for W */
|
ad_transfer(bp); /* MESSY!! only needed for W */
|
||||||
return;
|
return ATA_OP_CONTINUES;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bufq_remove(&adp->controller->ata_queue, bp);
|
bufq_remove(&adp->controller->ata_queue, bp);
|
||||||
@ -538,12 +532,11 @@ oops:
|
|||||||
biodone(bp);
|
biodone(bp);
|
||||||
adp->active = 0;
|
adp->active = 0;
|
||||||
}
|
}
|
||||||
adp->controller->active = ATA_IDLE;
|
|
||||||
ad_start(adp);
|
ad_start(adp);
|
||||||
#ifdef AD_DEBUG
|
#ifdef AD_DEBUG
|
||||||
printf("ad_interrupt: completed\n");
|
printf("ad_interrupt: completed\n");
|
||||||
#endif
|
#endif
|
||||||
ata_start(adp->controller);
|
return ATA_OP_FINISHED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: ata-disk.h,v 1.2 1999/03/03 21:10:29 sos Exp $
|
* $Id: ata-disk.h,v 1.3 1999/03/05 09:43:30 sos Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* ATA device parameter information */
|
/* ATA device parameter information */
|
||||||
@ -129,5 +129,5 @@ struct ad_softc {
|
|||||||
};
|
};
|
||||||
|
|
||||||
void ad_transfer(struct buf *);
|
void ad_transfer(struct buf *);
|
||||||
void ad_interrupt(struct buf *);
|
int32_t ad_interrupt(struct buf *);
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: atapi-all.c,v 1.2 1999/03/03 21:10:29 sos Exp $
|
* $Id: atapi-all.c,v 1.3 1999/03/05 09:43:30 sos Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ata.h"
|
#include "ata.h"
|
||||||
@ -49,7 +49,7 @@
|
|||||||
|
|
||||||
/* prototypes */
|
/* prototypes */
|
||||||
static void atapi_attach(void *);
|
static void atapi_attach(void *);
|
||||||
static int32_t atapi_get_param(struct atapi_softc *);
|
static int32_t atapi_getparam(struct atapi_softc *);
|
||||||
static int8_t *atapi_type(int32_t);
|
static int8_t *atapi_type(int32_t);
|
||||||
#ifdef ATAPI_DEBUG
|
#ifdef ATAPI_DEBUG
|
||||||
static int8_t *atapi_cmd2str(u_int8_t);
|
static int8_t *atapi_cmd2str(u_int8_t);
|
||||||
@ -85,7 +85,7 @@ atapi_attach(void *notused)
|
|||||||
bzero(atp, sizeof(struct atapi_softc));
|
bzero(atp, sizeof(struct atapi_softc));
|
||||||
atp->controller = atadevices[ctlr];
|
atp->controller = atadevices[ctlr];
|
||||||
atp->unit = (dev) ? ATA_SLAVE : ATA_MASTER;
|
atp->unit = (dev) ? ATA_SLAVE : ATA_MASTER;
|
||||||
if (atapi_get_param(atp)) {
|
if (atapi_getparam(atp)) {
|
||||||
free(atp, M_DEVBUF);
|
free(atp, M_DEVBUF);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -110,7 +110,6 @@ atapi_attach(void *notused)
|
|||||||
#endif
|
#endif
|
||||||
notfound:
|
notfound:
|
||||||
default:
|
default:
|
||||||
free(atp, M_DEVBUF);
|
|
||||||
bpack(atp->atapi_parm->model, model_buf, sizeof(model_buf));
|
bpack(atp->atapi_parm->model, model_buf, sizeof(model_buf));
|
||||||
bpack(atp->atapi_parm->revision, revision_buf,
|
bpack(atp->atapi_parm->revision, revision_buf,
|
||||||
sizeof(revision_buf));
|
sizeof(revision_buf));
|
||||||
@ -120,6 +119,7 @@ notfound:
|
|||||||
atapi_type(atp->atapi_parm->device_type),
|
atapi_type(atp->atapi_parm->device_type),
|
||||||
ctlr,
|
ctlr,
|
||||||
(dev) ? "slave" : "master ");
|
(dev) ? "slave" : "master ");
|
||||||
|
free(atp, M_DEVBUF);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -128,7 +128,7 @@ notfound:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int32_t
|
static int32_t
|
||||||
atapi_get_param(struct atapi_softc *atp)
|
atapi_getparam(struct atapi_softc *atp)
|
||||||
{
|
{
|
||||||
struct atapi_params *atapi_parm;
|
struct atapi_params *atapi_parm;
|
||||||
int8_t buffer[DEV_BSIZE];
|
int8_t buffer[DEV_BSIZE];
|
||||||
@ -157,7 +157,7 @@ atapi_get_param(struct atapi_softc *atp)
|
|||||||
|
|
||||||
int32_t
|
int32_t
|
||||||
atapi_queue_cmd(struct atapi_softc *atp, int8_t *ccb, void *data,
|
atapi_queue_cmd(struct atapi_softc *atp, int8_t *ccb, void *data,
|
||||||
int32_t count, int32_t flags,
|
int32_t count, int32_t flags, /*timeout,*/
|
||||||
atapi_callback_t callback, void *driver, struct buf *bp)
|
atapi_callback_t callback, void *driver, struct buf *bp)
|
||||||
{
|
{
|
||||||
struct atapi_request *request;
|
struct atapi_request *request;
|
||||||
@ -191,7 +191,7 @@ atapi_queue_cmd(struct atapi_softc *atp, int8_t *ccb, void *data,
|
|||||||
ata_start(atp->controller);
|
ata_start(atp->controller);
|
||||||
if (!callback) {
|
if (!callback) {
|
||||||
/* wait for command to complete */
|
/* wait for command to complete */
|
||||||
if (tsleep((caddr_t)request, PRIBIO, "atprq", 100))
|
if (tsleep((caddr_t)request, PRIBIO, "atprq", 0/*timeout*/))
|
||||||
error = 0xf0;
|
error = 0xf0;
|
||||||
else
|
else
|
||||||
error = request->result;
|
error = request->result;
|
||||||
@ -239,7 +239,7 @@ atapi_transfer(struct atapi_request *request)
|
|||||||
if (timeout <= 0) {
|
if (timeout <= 0) {
|
||||||
atp->controller->error = inb(atp->controller->ioaddr + ATA_ERROR);
|
atp->controller->error = inb(atp->controller->ioaddr + ATA_ERROR);
|
||||||
printf("atapi_transfer: bad command phase\n");
|
printf("atapi_transfer: bad command phase\n");
|
||||||
/* now what ?? SOS atapi-done & again */
|
/* now what ?? done & again ?? SOS */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* this seems to be needed for some (slow) devices */
|
/* this seems to be needed for some (slow) devices */
|
||||||
@ -250,7 +250,7 @@ atapi_transfer(struct atapi_request *request)
|
|||||||
request->ccbsize / sizeof(int16_t));
|
request->ccbsize / sizeof(int16_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
int32_t
|
||||||
atapi_interrupt(struct atapi_request *request)
|
atapi_interrupt(struct atapi_request *request)
|
||||||
{
|
{
|
||||||
struct atapi_softc *atp;
|
struct atapi_softc *atp;
|
||||||
@ -266,7 +266,7 @@ printf("atapi_interrupt: enter\n");
|
|||||||
if (atapi_wait(atp->controller, 0) < 0) {
|
if (atapi_wait(atp->controller, 0) < 0) {
|
||||||
printf("atapi_interrupt: timeout waiting for status");
|
printf("atapi_interrupt: timeout waiting for status");
|
||||||
/* maybe check sense code ?? SOS */
|
/* maybe check sense code ?? SOS */
|
||||||
return;
|
return ATA_OP_FINISHED;
|
||||||
}
|
}
|
||||||
atp->controller->status = inb(atp->controller->ioaddr + ATA_STATUS);
|
atp->controller->status = inb(atp->controller->ioaddr + ATA_STATUS);
|
||||||
atp->controller->error = inb(atp->controller->ioaddr + ATA_ERROR);
|
atp->controller->error = inb(atp->controller->ioaddr + ATA_ERROR);
|
||||||
@ -289,7 +289,7 @@ printf("atapi_interrupt: length=%d reason=0x%02x\n", length, reason);
|
|||||||
else
|
else
|
||||||
outsw(atp->controller->ioaddr + ATA_DATA, request->ccb,
|
outsw(atp->controller->ioaddr + ATA_DATA, request->ccb,
|
||||||
request->ccbsize / sizeof(int16_t));
|
request->ccbsize / sizeof(int16_t));
|
||||||
return;
|
return ATA_OP_CONTINUES;
|
||||||
|
|
||||||
case ATAPI_P_WRITE:
|
case ATAPI_P_WRITE:
|
||||||
if (request->flags & A_READ) {
|
if (request->flags & A_READ) {
|
||||||
@ -312,7 +312,7 @@ printf("atapi_interrupt: length=%d reason=0x%02x\n", length, reason);
|
|||||||
}
|
}
|
||||||
request->bytecount -= length;
|
request->bytecount -= length;
|
||||||
request->data += length;
|
request->data += length;
|
||||||
return;
|
return ATA_OP_CONTINUES;
|
||||||
|
|
||||||
case ATAPI_P_READ:
|
case ATAPI_P_READ:
|
||||||
if (!(request->flags & A_READ)) {
|
if (!(request->flags & A_READ)) {
|
||||||
@ -335,7 +335,7 @@ printf("atapi_interrupt: length=%d reason=0x%02x\n", length, reason);
|
|||||||
}
|
}
|
||||||
request->bytecount -= length;
|
request->bytecount -= length;
|
||||||
request->data += length;
|
request->data += length;
|
||||||
return;
|
return ATA_OP_CONTINUES;
|
||||||
|
|
||||||
case ATAPI_P_ABORT:
|
case ATAPI_P_ABORT:
|
||||||
case ATAPI_P_DONE:
|
case ATAPI_P_DONE:
|
||||||
@ -353,7 +353,7 @@ printf("atapi_interrupt: length=%d reason=0x%02x\n", length, reason);
|
|||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printf("atapi_interrupt: unknown transfer phase\n");
|
printf("atapi_interrupt: unknown transfer phase %d\n", reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
TAILQ_REMOVE(&atp->controller->atapi_queue, request, chain);
|
TAILQ_REMOVE(&atp->controller->atapi_queue, request, chain);
|
||||||
@ -366,8 +366,7 @@ printf("atapi_interrupt: error=0x%02x\n", request->result);
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
wakeup((caddr_t)request);
|
wakeup((caddr_t)request);
|
||||||
atp->controller->active = ATA_IDLE;
|
return ATA_OP_FINISHED;
|
||||||
ata_start(atp->controller);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -459,6 +458,7 @@ atapi_wait(struct ata_softc *scp, u_int8_t mask)
|
|||||||
status = inb(scp->ioaddr + ATA_STATUS);
|
status = inb(scp->ioaddr + ATA_STATUS);
|
||||||
if ((status == 0xff) && (scp->flags & ATA_F_SLAVE_ONLY)) {
|
if ((status == 0xff) && (scp->flags & ATA_F_SLAVE_ONLY)) {
|
||||||
outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | ATA_SLAVE);
|
outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | ATA_SLAVE);
|
||||||
|
DELAY(1);
|
||||||
status = inb(scp->ioaddr + ATA_STATUS);
|
status = inb(scp->ioaddr + ATA_STATUS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: atapi-all.h,v 1.1 1999/03/01 21:19:18 sos Exp $
|
* $Id: atapi-all.h,v 1.2 1999/03/03 21:10:29 sos Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* ATAPI misc defines */
|
/* ATAPI misc defines */
|
||||||
@ -147,6 +147,29 @@ struct atapi_params {
|
|||||||
u_int16_t rls_service; /* rel time (us) for service */
|
u_int16_t rls_service; /* rel time (us) for service */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* ATAPI REQUEST SENSE structure */
|
||||||
|
struct reqsense {
|
||||||
|
u_int8_t error_code :7; /* current or deferred errors */
|
||||||
|
u_int8_t valid :1; /* follows QIC-157C */
|
||||||
|
u_int8_t reserved1; /* Segment number - reserved */
|
||||||
|
u_int8_t sense_key :4; /* sense key */
|
||||||
|
u_int8_t reserved2_4 :1; /* reserved */
|
||||||
|
u_int8_t ili :1; /* incorrect length indicator */
|
||||||
|
u_int8_t eom :1; /* end of medium */
|
||||||
|
u_int8_t filemark :1; /* filemark */
|
||||||
|
u_int8_t info __attribute__((packed)); /* cmd specific info */
|
||||||
|
u_int8_t asl; /* additional sense length (n-7) */
|
||||||
|
u_int8_t command_specific; /* additional cmd specific info */
|
||||||
|
u_int8_t asc; /* additional sense code */
|
||||||
|
u_int8_t ascq; /* additional sense code qualifier */
|
||||||
|
u_int8_t replaceable_unit_code; /* field replaceable unit code */
|
||||||
|
u_int8_t sk_specific1 :7; /* sense key specific */
|
||||||
|
u_int8_t sksv :1; /* sense key specific info valid */
|
||||||
|
u_int8_t sk_specific2; /* sense key specific */
|
||||||
|
u_int8_t sk_specific3; /* sense key Specific */
|
||||||
|
u_int8_t pad[2]; /* padding */
|
||||||
|
};
|
||||||
|
|
||||||
struct atapi_softc {
|
struct atapi_softc {
|
||||||
struct ata_softc *controller; /* ptr to parent ctrl */
|
struct ata_softc *controller; /* ptr to parent ctrl */
|
||||||
struct atapi_params *atapi_parm; /* ata device params */
|
struct atapi_params *atapi_parm; /* ata device params */
|
||||||
@ -173,8 +196,8 @@ struct atapi_request {
|
|||||||
};
|
};
|
||||||
|
|
||||||
void atapi_transfer(struct atapi_request *);
|
void atapi_transfer(struct atapi_request *);
|
||||||
void atapi_interrupt(struct atapi_request *);
|
int32_t atapi_interrupt(struct atapi_request *);
|
||||||
int atapi_queue_cmd(struct atapi_softc *, int8_t [], void *, int32_t, int32_t, atapi_callback_t, void *, struct buf *);
|
int32_t atapi_queue_cmd(struct atapi_softc *, int8_t [], void *, int32_t, int32_t, atapi_callback_t, void *, struct buf *);
|
||||||
void atapi_error(struct atapi_softc *, int32_t);
|
void atapi_error(struct atapi_softc *, int32_t);
|
||||||
void atapi_dump(int8_t *, void *, int32_t);
|
void atapi_dump(int8_t *, void *, int32_t);
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: atapi-fd.c,v 1.1 1999/03/03 21:10:29 sos Exp $
|
* $Id: atapi-fd.c,v 1.2 1999/03/05 09:43:30 sos Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ata.h"
|
#include "ata.h"
|
||||||
@ -69,7 +69,9 @@ static struct cdevsw afd_cdevsw = {
|
|||||||
afdopen, afdclose, afdread, afdwrite,
|
afdopen, afdclose, afdread, afdwrite,
|
||||||
afdioctl, nostop, nullreset, nodevtotty,
|
afdioctl, nostop, nullreset, nodevtotty,
|
||||||
seltrue, nommap, afdstrategy, "afd",
|
seltrue, nommap, afdstrategy, "afd",
|
||||||
NULL, -1 };
|
NULL, -1, nodump, nopsize,
|
||||||
|
D_DISK, 0, -1
|
||||||
|
};
|
||||||
|
|
||||||
#define NUNIT 8
|
#define NUNIT 8
|
||||||
#define UNIT(d) ((minor(d) >> 3) & 3)
|
#define UNIT(d) ((minor(d) >> 3) & 3)
|
||||||
@ -257,8 +259,13 @@ afdioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p)
|
|||||||
if (lun >= afdnlun || !(fdp = afdtab[lun]))
|
if (lun >= afdnlun || !(fdp = afdtab[lun]))
|
||||||
return ENXIO;
|
return ENXIO;
|
||||||
|
|
||||||
switch (cmd) {
|
error = dsioctl("sd", dev, cmd, addr, flag, &fdp->slices,
|
||||||
|
afd_strategy, (ds_setgeom_t *)NULL);
|
||||||
|
|
||||||
|
if (error != ENOIOCTL)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
switch (cmd) {
|
||||||
case CDIOCEJECT:
|
case CDIOCEJECT:
|
||||||
if ((fdp->flags & F_OPEN) && fdp->refcnt)
|
if ((fdp->flags & F_OPEN) && fdp->refcnt)
|
||||||
return EBUSY;
|
return EBUSY;
|
||||||
@ -328,6 +335,9 @@ afd_start(struct afd_softc *fdp)
|
|||||||
lba = bp->b_blkno / (fdp->cap.sector_size / DEV_BSIZE);
|
lba = bp->b_blkno / (fdp->cap.sector_size / DEV_BSIZE);
|
||||||
count = (bp->b_bcount + (fdp->cap.sector_size - 1)) / fdp->cap.sector_size;
|
count = (bp->b_bcount + (fdp->cap.sector_size - 1)) / fdp->cap.sector_size;
|
||||||
|
|
||||||
|
if (count > 64) /* only needed for ZIP drives SOS */
|
||||||
|
count = 64;
|
||||||
|
|
||||||
if (bp->b_flags & B_READ)
|
if (bp->b_flags & B_READ)
|
||||||
ccb[0] = ATAPI_READ_BIG;
|
ccb[0] = ATAPI_READ_BIG;
|
||||||
else
|
else
|
||||||
@ -343,7 +353,7 @@ afd_start(struct afd_softc *fdp)
|
|||||||
|
|
||||||
devstat_start_transaction(&fdp->stats);
|
devstat_start_transaction(&fdp->stats);
|
||||||
|
|
||||||
atapi_queue_cmd(fdp->atp, ccb, bp->b_data, bp->b_bcount,
|
atapi_queue_cmd(fdp->atp, ccb, bp->b_data, count*fdp->cap.sector_size,
|
||||||
(bp->b_flags & B_READ) ? A_READ : 0, afd_done, fdp, bp);
|
(bp->b_flags & B_READ) ? A_READ : 0, afd_done, fdp, bp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: atapi-tape.c,v 1.2 1999/03/03 21:10:29 sos Exp $
|
* $Id: atapi-tape.c,v 1.3 1999/03/05 09:43:30 sos Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ata.h"
|
#include "ata.h"
|
||||||
@ -65,7 +65,9 @@ static struct cdevsw ast_cdevsw = {
|
|||||||
astopen, astclose, astread, astwrite,
|
astopen, astclose, astread, astwrite,
|
||||||
astioctl, nostop, nullreset, nodevtotty,
|
astioctl, nostop, nullreset, nodevtotty,
|
||||||
seltrue, nommap, aststrategy, "ast",
|
seltrue, nommap, aststrategy, "ast",
|
||||||
NULL, -1 };
|
NULL, -1, nodump, nopsize,
|
||||||
|
D_TAPE, 0, -1
|
||||||
|
};
|
||||||
|
|
||||||
static u_int32_t ast_total = 0;
|
static u_int32_t ast_total = 0;
|
||||||
|
|
||||||
|
@ -25,12 +25,11 @@
|
|||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: atapi-tape.h,v 1.1 1999/03/01 21:19:18 sos Exp $
|
* $Id: atapi-tape.h,v 1.2 1999/03/03 21:10:29 sos Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* ATAPI tape commands not in std ATAPI command set */
|
/* ATAPI tape commands not in std ATAPI command set */
|
||||||
#define ATAPI_TAPE_REWIND 0x01
|
#define ATAPI_TAPE_REWIND 0x01
|
||||||
#define ATAPI_TAPE_REQUEST_SENSE 0x03
|
|
||||||
#define ATAPI_TAPE_READ_CMD 0x08
|
#define ATAPI_TAPE_READ_CMD 0x08
|
||||||
#define ATAPI_TAPE_WRITE_CMD 0x0a
|
#define ATAPI_TAPE_WRITE_CMD 0x0a
|
||||||
#define ATAPI_TAPE_WEOF 0x10
|
#define ATAPI_TAPE_WEOF 0x10
|
||||||
@ -95,29 +94,6 @@ struct ast_cappage {
|
|||||||
u_int8_t reserved19;
|
u_int8_t reserved19;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* REQUEST SENSE structure */
|
|
||||||
struct ast_reqsense {
|
|
||||||
u_int8_t error_code :7; /* current or deferred errors */
|
|
||||||
u_int8_t valid :1; /* follows QIC-157C */
|
|
||||||
u_int8_t reserved1; /* Segment number - reserved */
|
|
||||||
u_int8_t sense_key :4; /* sense key */
|
|
||||||
u_int8_t reserved2_4 :1; /* reserved */
|
|
||||||
u_int8_t ili :1; /* incorrect length indicator */
|
|
||||||
u_int8_t eom :1; /* end of medium */
|
|
||||||
u_int8_t filemark :1; /* filemark */
|
|
||||||
u_int8_t info __attribute__((packed)); /* cmd specific info */
|
|
||||||
u_int8_t asl; /* additional sense length (n-7) */
|
|
||||||
u_int8_t command_specific; /* additional cmd specific info */
|
|
||||||
u_int8_t asc; /* additional sense code */
|
|
||||||
u_int8_t ascq; /* additional sense code qualifier */
|
|
||||||
u_int8_t replaceable_unit_code; /* field replaceable unit code */
|
|
||||||
u_int8_t sk_specific1 :7; /* sense key specific */
|
|
||||||
u_int8_t sksv :1; /* sense key specific info valid */
|
|
||||||
u_int8_t sk_specific2; /* sense key specific */
|
|
||||||
u_int8_t sk_specific3; /* sense key Specific */
|
|
||||||
u_int8_t pad[2]; /* padding */
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ast_softc {
|
struct ast_softc {
|
||||||
struct atapi_softc *atp; /* controller structure */
|
struct atapi_softc *atp; /* controller structure */
|
||||||
int32_t lun; /* logical device unit */
|
int32_t lun; /* logical device unit */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user