Pull the pst driver out from under GAINT.

This commit is contained in:
Søren Schmidt 2003-04-28 08:10:27 +00:00
parent 306babd20c
commit ac9953bfdd
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=114154
4 changed files with 150 additions and 74 deletions

View File

@ -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;
}

View File

@ -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;

View File

@ -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 }
};

View File

@ -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;