Pull the pst driver out from under GAINT.
This commit is contained in:
parent
306babd20c
commit
ac9953bfdd
@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 2001,2002 Søren Schmidt <sos@FreeBSD.org>
|
||||
* Copyright (c) 2001,2002,2003 Søren Schmidt <sos@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -35,6 +35,8 @@
|
||||
#include <sys/bus.h>
|
||||
#include <sys/bio.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <vm/vm.h>
|
||||
#include <vm/pmap.h>
|
||||
#include <machine/stdarg.h>
|
||||
@ -46,6 +48,11 @@
|
||||
|
||||
#include "dev/pst/pst-iop.h"
|
||||
|
||||
struct iop_request {
|
||||
struct i2o_single_reply *reply;
|
||||
u_int32_t mfa;
|
||||
};
|
||||
|
||||
/* local vars */
|
||||
MALLOC_DEFINE(M_PSTIOP, "PSTIOP", "Promise SuperTrak IOP driver");
|
||||
|
||||
@ -136,13 +143,19 @@ iop_attach(struct iop_softc *sc)
|
||||
continue;
|
||||
|
||||
switch (sc->lct[i].class) {
|
||||
case I2O_CLASS_DDM:
|
||||
if (sc->lct[i].sub_class == I2O_SUBCLASS_ISM)
|
||||
sc->ism = sc->lct[i].local_tid;
|
||||
break;
|
||||
|
||||
case I2O_CLASS_RANDOM_BLOCK_STORAGE:
|
||||
pst_add_raid(sc, &sc->lct[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* setup and enable interrupts */
|
||||
bus_setup_intr(sc->dev, sc->r_irq, INTR_TYPE_BIO | INTR_ENTROPY,
|
||||
bus_setup_intr(sc->dev, sc->r_irq, INTR_TYPE_BIO|INTR_ENTROPY|INTR_MPSAFE,
|
||||
iop_intr, sc, &sc->handle);
|
||||
sc->reg->oqueue_intr_mask = 0x0;
|
||||
}
|
||||
@ -155,21 +168,22 @@ iop_intr(void *data)
|
||||
u_int32_t mfa;
|
||||
|
||||
/* we might get more than one finished request pr interrupt */
|
||||
mtx_lock(&sc->mtx);
|
||||
while (1) {
|
||||
if ((mfa = sc->reg->oqueue) == 0xffffffff)
|
||||
if ((mfa = sc->reg->oqueue) == 0xffffffff)
|
||||
return;
|
||||
break;
|
||||
|
||||
reply = (struct i2o_single_reply *)(sc->obase + (mfa - sc->phys_obase));
|
||||
|
||||
/* If this is an event register reply, shout! */
|
||||
/* if this is an event register reply, shout! */
|
||||
if (reply->function == I2O_UTIL_EVENT_REGISTER) {
|
||||
struct i2o_util_event_reply_message *event =
|
||||
(struct i2o_util_event_reply_message *)reply;
|
||||
|
||||
printf("pstiop: EVENT!! idx=%08x data=%08x\n",
|
||||
event->event_mask, event->event_data[0]);
|
||||
return;
|
||||
break;
|
||||
}
|
||||
|
||||
/* if reply is a failurenotice we need to free the original mfa */
|
||||
@ -180,6 +194,7 @@ iop_intr(void *data)
|
||||
((void (*)(struct iop_softc *, u_int32_t, struct i2o_single_reply *))
|
||||
(reply->initiator_context))(sc, mfa, reply);
|
||||
}
|
||||
mtx_unlock(&sc->mtx);
|
||||
}
|
||||
|
||||
int
|
||||
@ -226,7 +241,7 @@ iop_init_outqueue(struct iop_softc *sc)
|
||||
I2O_IOP_OUTBOUND_FRAME_SIZE,
|
||||
M_PSTIOP, M_NOWAIT,
|
||||
0x00010000, 0xFFFFFFFF,
|
||||
sizeof(u_int32_t), 0))) {
|
||||
PAGE_SIZE, 0))) {
|
||||
printf("pstiop: contigmalloc of outqueue buffers failed!\n");
|
||||
return 0;
|
||||
}
|
||||
@ -268,7 +283,6 @@ iop_init_outqueue(struct iop_softc *sc)
|
||||
DELAY(1000);
|
||||
}
|
||||
|
||||
iop_free_mfa(sc, mfa);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -281,7 +295,7 @@ iop_get_lct(struct iop_softc *sc)
|
||||
#define ALLOCSIZE (PAGE_SIZE + (256 * sizeof(struct i2o_lct_entry)))
|
||||
|
||||
if (!(reply = contigmalloc(ALLOCSIZE, M_PSTIOP, M_NOWAIT | M_ZERO,
|
||||
0x00010000, 0xFFFFFFFF, sizeof(u_int32_t), 0)))
|
||||
0x00010000, 0xFFFFFFFF, PAGE_SIZE, 0)))
|
||||
return 0;
|
||||
|
||||
mfa = iop_get_mfa(sc);
|
||||
@ -325,11 +339,11 @@ iop_get_util_params(struct iop_softc *sc, int target, int operation, int group)
|
||||
int mfa;
|
||||
|
||||
if (!(param = contigmalloc(PAGE_SIZE, M_PSTIOP, M_NOWAIT | M_ZERO,
|
||||
0x00010000, 0xFFFFFFFF, sizeof(u_int32_t), 0)))
|
||||
0x00010000, 0xFFFFFFFF, PAGE_SIZE, 0)))
|
||||
return NULL;
|
||||
|
||||
if (!(reply = contigmalloc(PAGE_SIZE, M_PSTIOP, M_NOWAIT | M_ZERO,
|
||||
0x00010000, 0xFFFFFFFF, sizeof(u_int32_t), 0)))
|
||||
0x00010000, 0xFFFFFFFF, PAGE_SIZE, 0)))
|
||||
return NULL;
|
||||
|
||||
mfa = iop_get_mfa(sc);
|
||||
@ -395,25 +409,54 @@ iop_free_mfa(struct iop_softc *sc, int mfa)
|
||||
sc->reg->iqueue = mfa;
|
||||
}
|
||||
|
||||
static void
|
||||
iop_done(struct iop_softc *sc, u_int32_t mfa, struct i2o_single_reply *reply)
|
||||
{
|
||||
struct iop_request *request =
|
||||
(struct iop_request *)reply->transaction_context;
|
||||
|
||||
request->reply = reply;
|
||||
request->mfa = mfa;
|
||||
wakeup(request);
|
||||
}
|
||||
|
||||
int
|
||||
iop_queue_wait_msg(struct iop_softc *sc, int mfa, struct i2o_basic_message *msg)
|
||||
{
|
||||
struct i2o_single_reply *reply;
|
||||
int out_mfa, status, timeout = 10000;
|
||||
struct iop_request request;
|
||||
u_int32_t out_mfa;
|
||||
int status, timeout = 10000;
|
||||
|
||||
sc->reg->iqueue = mfa;
|
||||
|
||||
while (--timeout && ((out_mfa = sc->reg->oqueue) == 0xffffffff))
|
||||
DELAY(1000);
|
||||
if (!timeout) {
|
||||
printf("pstiop: timeout waiting for message response\n");
|
||||
iop_free_mfa(sc, mfa);
|
||||
return -1;
|
||||
mtx_lock(&sc->mtx);
|
||||
if (!(sc->reg->oqueue_intr_mask & 0x08)) {
|
||||
msg->transaction_context = (u_int32_t)&request;
|
||||
msg->initiator_context = (u_int32_t)iop_done;
|
||||
sc->reg->iqueue = mfa;
|
||||
if (msleep(&request, &sc->mtx, PRIBIO, "pstwt", 10 * hz)) {
|
||||
printf("pstiop: timeout waiting for message response\n");
|
||||
iop_free_mfa(sc, mfa);
|
||||
mtx_unlock(&sc->mtx);
|
||||
return -1;
|
||||
}
|
||||
status = request.reply->status;
|
||||
sc->reg->oqueue = request.mfa;
|
||||
}
|
||||
|
||||
reply = (struct i2o_single_reply *)(sc->obase + (out_mfa - sc->phys_obase));
|
||||
status = reply->status;
|
||||
sc->reg->oqueue = out_mfa;
|
||||
else {
|
||||
sc->reg->iqueue = mfa;
|
||||
while (--timeout && ((out_mfa = sc->reg->oqueue) == 0xffffffff))
|
||||
DELAY(1000);
|
||||
if (!timeout) {
|
||||
printf("pstiop: timeout waiting for message response\n");
|
||||
iop_free_mfa(sc, mfa);
|
||||
mtx_unlock(&sc->mtx);
|
||||
return -1;
|
||||
}
|
||||
reply = (struct i2o_single_reply *)(sc->obase+(out_mfa-sc->phys_obase));
|
||||
status = reply->status;
|
||||
sc->reg->oqueue = out_mfa;
|
||||
}
|
||||
mtx_unlock(&sc->mtx);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 2001,2002 Søren Schmidt <sos@FreeBSD.org>
|
||||
* Copyright (c) 2001,2002,2003 Søren Schmidt <sos@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -49,7 +49,10 @@ struct iop_softc {
|
||||
struct i2o_status_get_reply *status;
|
||||
int lct_count;
|
||||
struct i2o_lct_entry *lct;
|
||||
int ism;
|
||||
device_t dev;
|
||||
struct mtx mtx;
|
||||
int outstanding;
|
||||
void *handle;
|
||||
struct intr_config_hook *iop_delayed_attach;
|
||||
};
|
||||
@ -121,6 +124,7 @@ struct i2o_sgl {
|
||||
#define I2O_EXEC_SYSTAB_SET 0xa3
|
||||
#define I2O_EXEC_IOP_RESET 0xbd
|
||||
#define I2O_EXEC_SYS_ENABLE 0xd1
|
||||
#define I2O_PRIVATE_MESSAGE 0xff
|
||||
|
||||
/* basic message layout */
|
||||
struct i2o_basic_message {
|
||||
@ -498,7 +502,7 @@ struct i2o_get_param_operation {
|
||||
} __packed;
|
||||
|
||||
struct i2o_get_param_reply {
|
||||
u_int16_t result_count;;
|
||||
u_int16_t result_count;
|
||||
u_int16_t reserved;
|
||||
u_int16_t block_size;
|
||||
u_int8_t block_status;
|
||||
@ -580,6 +584,21 @@ struct i2o_util_config_dialog_message {
|
||||
struct i2o_sgl sgl[2];
|
||||
} __packed;
|
||||
|
||||
struct i2o_private_message {
|
||||
u_int8_t version_offset;
|
||||
u_int8_t message_flags;
|
||||
u_int16_t message_size;
|
||||
u_int32_t target_address:12;
|
||||
u_int32_t initiator_address:12;
|
||||
u_int32_t function:8;
|
||||
u_int32_t initiator_context;
|
||||
u_int32_t transaction_context;
|
||||
u_int16_t function_code;
|
||||
u_int16_t organization_id;
|
||||
struct i2o_sgl in_sgl;
|
||||
struct i2o_sgl out_sgl;
|
||||
} __packed;
|
||||
|
||||
struct i2o_bsa_rw_block_message {
|
||||
u_int8_t version_offset;
|
||||
u_int8_t message_flags;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 2001,2002 Søren Schmidt <sos@FreeBSD.org>
|
||||
* Copyright (c) 2001,2002,2003 Søren Schmidt <sos@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -35,6 +35,8 @@
|
||||
#include <sys/bus.h>
|
||||
#include <sys/bio.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <vm/vm.h>
|
||||
#include <vm/pmap.h>
|
||||
#include <machine/stdarg.h>
|
||||
@ -93,16 +95,29 @@ iop_pci_attach(device_t dev)
|
||||
sc->phys_ibase = vtophys(sc->ibase);
|
||||
sc->reg = (struct i2o_registers *)sc->ibase;
|
||||
sc->dev = dev;
|
||||
mtx_init(&sc->mtx, "pst lock", MTX_DEF, 0);
|
||||
|
||||
if (!iop_init(sc))
|
||||
return 0;
|
||||
|
||||
return bus_generic_attach(dev);
|
||||
}
|
||||
|
||||
static int
|
||||
iop_pci_detach(device_t dev)
|
||||
{
|
||||
struct iop_softc *sc = device_get_softc(dev);
|
||||
|
||||
bus_teardown_intr(dev, sc->r_irq, sc->handle);
|
||||
bus_release_resource(dev, SYS_RES_IRQ, 0x00, sc->r_irq);
|
||||
bus_release_resource(dev, SYS_RES_MEMORY, 0x10, sc->r_mem);
|
||||
return bus_generic_detach(dev);
|
||||
}
|
||||
|
||||
|
||||
static device_method_t pst_pci_methods[] = {
|
||||
DEVMETHOD(device_probe, iop_pci_probe),
|
||||
DEVMETHOD(device_attach, iop_pci_attach),
|
||||
DEVMETHOD(device_detach, iop_pci_detach),
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 2001,2002 Søren Schmidt <sos@FreeBSD.org>
|
||||
* Copyright (c) 2001,2002,2003 Søren Schmidt <sos@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -57,8 +57,6 @@ struct pst_softc {
|
||||
struct i2o_bsa_device *info;
|
||||
struct disk disk;
|
||||
struct bio_queue_head queue;
|
||||
struct mtx mtx;
|
||||
int outstanding;
|
||||
};
|
||||
|
||||
struct pst_request {
|
||||
@ -149,13 +147,12 @@ pst_attach(device_t dev)
|
||||
contigfree(reply, PAGE_SIZE, M_PSTRAID);
|
||||
|
||||
bioq_init(&psc->queue);
|
||||
mtx_init(&psc->mtx, "pst lock", MTX_DEF, 0);
|
||||
|
||||
psc->disk.d_name = "pst";
|
||||
psc->disk.d_strategy = pststrategy;
|
||||
psc->disk.d_maxsize = 64 * 1024; /*I2O_SGL_MAX_SEGS * PAGE_SIZE;*/
|
||||
psc->disk.d_drv1 = psc;
|
||||
disk_create(lun, &psc->disk, 0, NULL, NULL);
|
||||
disk_create(lun, &psc->disk, DISKFLAG_NOGIANT, NULL, NULL);
|
||||
|
||||
psc->disk.d_sectorsize = psc->info->block_size;
|
||||
psc->disk.d_mediasize = psc->info->capacity;
|
||||
@ -199,10 +196,10 @@ pststrategy(struct bio *bp)
|
||||
{
|
||||
struct pst_softc *psc = bp->bio_disk->d_drv1;
|
||||
|
||||
mtx_lock(&psc->mtx);
|
||||
mtx_lock(&psc->iop->mtx);
|
||||
bioq_disksort(&psc->queue, bp);
|
||||
pst_start(psc);
|
||||
mtx_unlock(&psc->mtx);
|
||||
mtx_unlock(&psc->iop->mtx);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -212,7 +209,7 @@ pst_start(struct pst_softc *psc)
|
||||
struct bio *bp;
|
||||
u_int32_t mfa;
|
||||
|
||||
if (psc->outstanding < (I2O_IOP_OUTBOUND_FRAME_COUNT - 1) &&
|
||||
if (psc->iop->outstanding < (I2O_IOP_OUTBOUND_FRAME_COUNT - 1) &&
|
||||
(bp = bioq_first(&psc->queue))) {
|
||||
if ((mfa = iop_get_mfa(psc->iop)) != 0xffffffff) {
|
||||
bioq_remove(&psc->queue, bp);
|
||||
@ -223,19 +220,14 @@ pst_start(struct pst_softc *psc)
|
||||
iop_free_mfa(psc->iop, mfa);
|
||||
return;
|
||||
}
|
||||
psc->outstanding++;
|
||||
psc->iop->outstanding++;
|
||||
request->psc = psc;
|
||||
request->mfa = mfa;
|
||||
request->bp = bp;
|
||||
if (dumping)
|
||||
request->timeout_handle.callout = NULL;
|
||||
else
|
||||
request->timeout_handle =
|
||||
timeout((timeout_t*)pst_timeout, request, 10 * hz);
|
||||
if (pst_rw(request)) {
|
||||
biofinish(request->bp, NULL, EIO);
|
||||
iop_free_mfa(request->psc->iop, request->mfa);
|
||||
psc->outstanding--;
|
||||
psc->iop->outstanding--;
|
||||
free(request, M_PSTRAID);
|
||||
}
|
||||
}
|
||||
@ -253,38 +245,9 @@ pst_done(struct iop_softc *sc, u_int32_t mfa, struct i2o_single_reply *reply)
|
||||
request->bp->bio_resid = request->bp->bio_bcount - reply->donecount;
|
||||
biofinish(request->bp, NULL, reply->status ? EIO : 0);
|
||||
free(request, M_PSTRAID);
|
||||
mtx_lock(&psc->mtx);
|
||||
psc->iop->reg->oqueue = mfa;
|
||||
psc->outstanding--;
|
||||
psc->iop->outstanding--;
|
||||
pst_start(psc);
|
||||
mtx_unlock(&psc->mtx);
|
||||
}
|
||||
|
||||
static void
|
||||
pst_timeout(struct pst_request *request)
|
||||
{
|
||||
printf("pst: timeout mfa=0x%08x cmd=0x%02x\n",
|
||||
request->mfa, request->bp->bio_cmd);
|
||||
mtx_lock(&request->psc->mtx);
|
||||
iop_free_mfa(request->psc->iop, request->mfa);
|
||||
if ((request->mfa = iop_get_mfa(request->psc->iop)) == 0xffffffff) {
|
||||
printf("pst: timeout no mfa possible\n");
|
||||
biofinish(request->bp, NULL, EIO);
|
||||
request->psc->outstanding--;
|
||||
mtx_unlock(&request->psc->mtx);
|
||||
return;
|
||||
}
|
||||
if (dumping)
|
||||
request->timeout_handle.callout = NULL;
|
||||
else
|
||||
request->timeout_handle =
|
||||
timeout((timeout_t*)pst_timeout, request, 10 * hz);
|
||||
if (pst_rw(request)) {
|
||||
iop_free_mfa(request->psc->iop, request->mfa);
|
||||
biofinish(request->bp, NULL, EIO);
|
||||
request->psc->outstanding--;
|
||||
}
|
||||
mtx_unlock(&request->psc->mtx);
|
||||
}
|
||||
|
||||
int
|
||||
@ -315,7 +278,7 @@ pst_rw(struct pst_request *request)
|
||||
sgl_flag = I2O_SGL_DIR;
|
||||
break;
|
||||
default:
|
||||
printf("pst: unknown command type\n");
|
||||
printf("pst: unknown command type 0x%02x\n", request->bp->bio_cmd);
|
||||
return -1;
|
||||
}
|
||||
msg->initiator_context = (u_int32_t)pst_done;
|
||||
@ -323,13 +286,48 @@ pst_rw(struct pst_request *request)
|
||||
msg->time_multiplier = 1;
|
||||
msg->bytecount = request->bp->bio_bcount;
|
||||
msg->lba = ((u_int64_t)request->bp->bio_pblkno) * (DEV_BSIZE * 1LL);
|
||||
|
||||
if (!iop_create_sgl((struct i2o_basic_message *)msg, request->bp->bio_data,
|
||||
request->bp->bio_bcount, sgl_flag))
|
||||
return -1;
|
||||
|
||||
request->psc->iop->reg->iqueue = request->mfa;
|
||||
|
||||
if (dumping)
|
||||
request->timeout_handle.callout = NULL;
|
||||
else
|
||||
request->timeout_handle =
|
||||
timeout((timeout_t*)pst_timeout, request, 10 * hz);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
pst_timeout(struct pst_request *request)
|
||||
{
|
||||
printf("pst: timeout mfa=0x%08x cmd=0x%02x\n",
|
||||
request->mfa, request->bp->bio_cmd);
|
||||
mtx_lock(&request->psc->iop->mtx);
|
||||
iop_free_mfa(request->psc->iop, request->mfa);
|
||||
if ((request->mfa = iop_get_mfa(request->psc->iop)) == 0xffffffff) {
|
||||
printf("pst: timeout no mfa possible\n");
|
||||
biofinish(request->bp, NULL, EIO);
|
||||
request->psc->iop->outstanding--;
|
||||
mtx_unlock(&request->psc->iop->mtx);
|
||||
return;
|
||||
}
|
||||
if (dumping)
|
||||
request->timeout_handle.callout = NULL;
|
||||
else
|
||||
request->timeout_handle =
|
||||
timeout((timeout_t*)pst_timeout, request, 10 * hz);
|
||||
if (pst_rw(request)) {
|
||||
iop_free_mfa(request->psc->iop, request->mfa);
|
||||
biofinish(request->bp, NULL, EIO);
|
||||
request->psc->iop->outstanding--;
|
||||
}
|
||||
mtx_unlock(&request->psc->iop->mtx);
|
||||
}
|
||||
|
||||
static void
|
||||
bpack(int8_t *src, int8_t *dst, int len)
|
||||
{
|
||||
@ -337,7 +335,8 @@ bpack(int8_t *src, int8_t *dst, int len)
|
||||
int8_t *ptr, *buf = dst;
|
||||
|
||||
for (i = j = blank = 0 ; i < len; i++) {
|
||||
if (blank && src[i] == ' ') continue;
|
||||
if (blank && src[i] == ' ')
|
||||
continue;
|
||||
if (blank && src[i] != ' ') {
|
||||
dst[j++] = src[i];
|
||||
blank = 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user