mirror of
https://github.com/opnsense/src.git
synced 2026-05-28 04:12:45 -04:00
crashdump support.
Some bits by: Rajesh Prabhakaran <rajeshpr@lsil.com>
This commit is contained in:
parent
4b59e44a86
commit
6728a38bf2
3 changed files with 84 additions and 12 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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++;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
/********************************************************************************
|
||||
|
|
|
|||
Loading…
Reference in a new issue