crashdump support.

Some bits by:	Rajesh Prabhakaran <rajeshpr@lsil.com>
This commit is contained in:
Paul Saab 2003-10-10 22:49:40 +00:00
parent 4b59e44a86
commit 6728a38bf2
3 changed files with 84 additions and 12 deletions

View file

@ -977,20 +977,22 @@ amr_quartz_poll_command(struct amr_command *ac)
s = splbio();
count=0;
while (sc->amr_busyslots){
tsleep(sc, PRIBIO | PCATCH, "amrpoll", hz);
if(count++>10) {
break;
if (sc->amr_state & AMR_STATE_INTEN) {
count=0;
while (sc->amr_busyslots) {
tsleep(sc, PRIBIO | PCATCH, "amrpoll", hz);
if(count++>10) {
break;
}
}
}
if(sc->amr_busyslots) {
device_printf(sc->amr_dev, "adapter is busy\n");
splx(s);
amr_unmapcmd(ac);
ac->ac_status=0;
return(1);
if(sc->amr_busyslots) {
device_printf(sc->amr_dev, "adapter is busy\n");
splx(s);
amr_unmapcmd(ac);
ac->ac_status=0;
return(1);
}
}
bcopy(&ac->ac_mailbox, (void *)(uintptr_t)(volatile void *)sc->amr_mailbox, AMR_MBOX_CMDSIZE);
@ -1779,6 +1781,47 @@ amr_describe_controller(struct amr_softc *sc)
free(ae, M_DEVBUF);
}
int
amr_dump_blocks(struct amr_softc *sc, int unit, u_int32_t lba, void *data, int blks)
{
struct amr_command *ac;
int error = EIO;
debug_called(1);
sc->amr_state &= ~AMR_STATE_INTEN;
/* get ourselves a command buffer */
if ((ac = amr_alloccmd(sc)) == NULL)
goto out;
/* set command flags */
ac->ac_flags |= AMR_CMD_PRIORITY | AMR_CMD_DATAOUT;
/* point the command at our data */
ac->ac_data = data;
ac->ac_length = blks * AMR_BLKSIZE;
/* build the command proper */
ac->ac_mailbox.mb_command = AMR_CMD_LWRITE;
ac->ac_mailbox.mb_blkcount = blks;
ac->ac_mailbox.mb_lba = lba;
ac->ac_mailbox.mb_drive = unit;
/* can't assume that interrupts are going to work here, so play it safe */
if (sc->amr_poll_command(ac))
goto out;
error = ac->ac_status;
out:
if (ac != NULL)
amr_releasecmd(ac);
sc->amr_state |= AMR_STATE_INTEN;
return (error);
}
#ifdef AMR_DEBUG
/********************************************************************************
* Print the command (ac) in human-readable format

View file

@ -142,6 +142,33 @@ amrd_open(struct disk *dp)
return (0);
}
/********************************************************************************
* System crashdump support
*/
static int
amrd_dump(void *arg, void *virtual, vm_offset_t physical, off_t offset, size_t length)
{
struct amrd_softc *amrd_sc;
struct amr_softc *amr_sc;
int error;
struct disk *dp;
dp = arg;
amrd_sc = (struct amrd_softc *)dp->d_drv1;
amr_sc = (struct amr_softc *)amrd_sc->amrd_controller;
if (!amrd_sc || !amr_sc)
return(ENXIO);
if (length > 0) {
int driveno = amrd_sc->amrd_drive - amr_sc->amr_drive;
if ((error = amr_dump_blocks(amr_sc,driveno,offset / AMR_BLKSIZE ,(void *)virtual,(int) length / AMR_BLKSIZE )) != 0)
return(error);
}
return(0);
}
/*
* Read/write routine for a buffer. Finds the proper unit, range checks
@ -225,6 +252,7 @@ amrd_attach(device_t dev)
sc->amrd_disk.d_open = amrd_open;
sc->amrd_disk.d_strategy = amrd_strategy;
sc->amrd_disk.d_name = "amrd";
sc->amrd_disk.d_dump = (dumper_t *)amrd_dump;
disk_create(sc->amrd_unit, &sc->amrd_disk, 0, NULL, NULL);
#ifdef FREEBSD_4
disks_registered++;

View file

@ -261,6 +261,7 @@ struct amrd_softc
* Interface between driver core and disk driver (should be using a bus?)
*/
extern int amr_submit_bio(struct amr_softc *sc, struct bio *bio);
extern int amr_dump_blocks(struct amr_softc *sc, int unit, u_int32_t lba, void *data, int blks);
extern void amrd_intr(void *data);
/********************************************************************************