Writing Device Drivers

Dump Handling

dump(9E)

The dump(9E) entry point is used to copy a portion of virtual address space directly to the specified device in the case of system failure or checkpoint operation. See cpr(7) and dump(9E). The dump(9E) entry point must be capable of performing this operation without the use of interrupts.

dev is the device number of the dump device, addr is the kernel virtual address at which to start the dump, blkno is the first destination block on the device and nblk is the number of blocks to dump.


Example 13-9 dump(9E) Routine

static int
xxdump(dev_t dev, caddr_t addr, daddr_t blkno, int nblk)
{
	struct xxstate	*xsp;
	struct buf	*bp;
	struct scsi_pkt	*pkt;
	int		rval;
	int		instance;

	instance = getminor(dev);
	xsp = ddi_get_soft_state(statep, instance);

	if (tgt->suspended || tgt->pm_suspended) {
		(void) ddi_dev_is_needed(DEVINFO(tgt), 0, 1);
	}

	bp = getrbuf(KM_NOSLEEP);
	if (bp == NULL) {
		return (EIO);
	}

Calculate block number relative to partition
	
bp->b_un.b_addr = addr;
	bp->b_edev = dev;
	bp->b_bcount = nblk * DEV_BSIZE;
	bp->b_flags = B_WRITE | B_BUSY;
	bp->b_blkno = blkno;

	pkt = scsi_init_pkt(ROUTE(tgt), NULL, bp, CDB_GROUP1,
	    sizeof (struct scsi_arq_status),
	    sizeof (struct bst_pkt_private), 0, NULL_FUNC, NULL);

	if (pkt == NULL) {
		freerbuf(bp);
		return (EIO);
	}
	(void) scsi_setup_cdb((union scsi_cdb *)pkt->pkt_cdbp,
			SCMD_WRITE_G1, blkno, nblk, 0);

	/*
	 * while dumping in polled mode, other cmds might complete
	 * and these should not be resubmitted. we set the
	 * dumping flag here which prevents requeuing cmds.
	 */
	tgt->dumping = 1;
	rval = scsi_poll(pkt);
	tgt->dumping = 0;

	scsi_destroy_pkt(pkt);
	freerbuf(bp);

	if (rval != DDI_SUCCESS) {
		rval = EIO;
	}

	return (rval);
}