/*
 * File...........: linux/drivers/s390/block/dasd.c
 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
 *		    Horst Hummel <Horst.Hummel@de.ibm.com>
 *		    Carsten Otte <Cotte@de.ibm.com>
 *		    Martin Schwidefsky <schwidefsky@de.ibm.com>
 * Bugreports.to..: <Linux390@de.ibm.com>
 * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999-2001
 *
 */

#include <linux/config.h>
#include <linux/ctype.h>
#include <linux/init.h>

#include <asm/debug.h>
#include <asm/ebcdic.h>
#include <asm/uaccess.h>

/* This is ugly... */
#define PRINTK_HEADER "dasd_erp:"

#include "dasd_int.h"

struct dasd_ccw_req *
dasd_alloc_erp_request(char *magic, int cplength, int datasize,
		       struct dasd_device * device)
{
	unsigned long flags;
	struct dasd_ccw_req *cqr;
	char *data;
	int size;

	/* Sanity checks */
	BUG_ON( magic == NULL || datasize > PAGE_SIZE ||
	     (cplength*sizeof(struct ccw1)) > PAGE_SIZE);

	size = (sizeof(struct dasd_ccw_req) + 7L) & -8L;
	if (cplength > 0)
		size += cplength * sizeof(struct ccw1);
	if (datasize > 0)
		size += datasize;
	spin_lock_irqsave(&device->mem_lock, flags);
	cqr = (struct dasd_ccw_req *)
		dasd_alloc_chunk(&device->erp_chunks, size);
	spin_unlock_irqrestore(&device->mem_lock, flags);
	if (cqr == NULL)
		return ERR_PTR(-ENOMEM);
	memset(cqr, 0, sizeof(struct dasd_ccw_req));
	data = (char *) cqr + ((sizeof(struct dasd_ccw_req) + 7L) & -8L);
	cqr->cpaddr = NULL;
	if (cplength > 0) {
		cqr->cpaddr = (struct ccw1 *) data;
		data += cplength*sizeof(struct ccw1);
		memset(cqr->cpaddr, 0, cplength*sizeof(struct ccw1));
	}
	cqr->data = NULL;
	if (datasize > 0) {
		cqr->data = data;
 		memset(cqr->data, 0, datasize);
	}
	strncpy((char *) &cqr->magic, magic, 4);
	ASCEBC((char *) &cqr->magic, 4);
	set_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
	dasd_get_device(device);
	return cqr;
}

void
dasd_free_erp_request(struct dasd_ccw_req * cqr, struct dasd_device * device)
{
	unsigned long flags;

	spin_lock_irqsave(&device->mem_lock, flags);
	dasd_free_chunk(&device->erp_chunks, cqr);
	spin_unlock_irqrestore(&device->mem_lock, flags);
	atomic_dec(&device->ref_count);
}


/*
 * dasd_default_erp_action just retries the current cqr
 */
struct dasd_ccw_req *
dasd_default_erp_action(struct dasd_ccw_req * cqr)
{
	struct dasd_device *device;

	device = cqr->device;

        /* just retry - there is nothing to save ... I got no sense data.... */
        if (cqr->retries > 0) {
                DEV_MESSAGE (KERN_DEBUG, device, 
                             "default ERP called (%i retries left)",
                             cqr->retries);
		cqr->lpm    = LPM_ANYPATH;
		cqr->status = DASD_CQR_QUEUED;
        } else {
                DEV_MESSAGE (KERN_WARNING, device, "%s",
			     "default ERP called (NO retry left)");
		cqr->status = DASD_CQR_FAILED;
		cqr->stopclk = get_clock ();
        }
        return cqr;
}				/* end dasd_default_erp_action */

/*
 * DESCRIPTION
 *   Frees all ERPs of the current ERP Chain and set the status
 *   of the original CQR either to DASD_CQR_DONE if ERP was successful
 *   or to DASD_CQR_FAILED if ERP was NOT successful.
 *   NOTE: This function is only called if no discipline postaction
 *	   is available
 *
 * PARAMETER
 *   erp		current erp_head
 *
 * RETURN VALUES
 *   cqr		pointer to the original CQR
 */
struct dasd_ccw_req *
dasd_default_erp_postaction(struct dasd_ccw_req * cqr)
{
	struct dasd_device *device;
	int success;

	BUG_ON(cqr->refers == NULL || cqr->function == NULL);

	device = cqr->device;
	success = cqr->status == DASD_CQR_DONE;

	/* free all ERPs - but NOT the original cqr */
	while (cqr->refers != NULL) {
		struct dasd_ccw_req *refers;

		refers = cqr->refers;
		/* remove the request from the device queue */
		list_del(&cqr->list);
		/* free the finished erp request */
		dasd_free_erp_request(cqr, device);
		cqr = refers;
	}

	/* set corresponding status to original cqr */
	if (success)
		cqr->status = DASD_CQR_DONE;
	else {
		cqr->status = DASD_CQR_FAILED;
		cqr->stopclk = get_clock();
	}

	return cqr;

}				/* end default_erp_postaction */

/*
 * Print the hex dump of the memory used by a request. This includes
 * all error recovery ccws that have been chained in from of the 
 * real request.
 */
static inline void
hex_dump_memory(struct dasd_device *device, void *data, int len)
{
	int *pint;

	pint = (int *) data;
	while (len > 0) {
		DEV_MESSAGE(KERN_ERR, device, "%p: %08x %08x %08x %08x",
			    pint, pint[0], pint[1], pint[2], pint[3]);
		pint += 4;
		len -= 16;
	}
}

void
dasd_log_sense(struct dasd_ccw_req *cqr, struct irb *irb)
{
	struct dasd_device *device;

	device = cqr->device;
	/* dump sense data */
	if (device->discipline && device->discipline->dump_sense)
		device->discipline->dump_sense(device, cqr, irb);
}

void
dasd_log_ccw(struct dasd_ccw_req * cqr, int caller, __u32 cpa)
{
	struct dasd_device *device;
	struct dasd_ccw_req *lcqr;
	struct ccw1 *ccw;
	int cplength;

	device = cqr->device;
	/* log the channel program */
	for (lcqr = cqr; lcqr != NULL; lcqr = lcqr->refers) {
		DEV_MESSAGE(KERN_ERR, device,
			    "(%s) ERP chain report for req: %p",
			    caller == 0 ? "EXAMINE" : "ACTION", lcqr);
		hex_dump_memory(device, lcqr, sizeof(struct dasd_ccw_req));

		cplength = 1;
		ccw = lcqr->cpaddr;
		while (ccw++->flags & (CCW_FLAG_DC | CCW_FLAG_CC))
			cplength++;

		if (cplength > 40) {	/* log only parts of the CP */
			DEV_MESSAGE(KERN_ERR, device, "%s",
				    "Start of channel program:");
			hex_dump_memory(device, lcqr->cpaddr,
					40*sizeof(struct ccw1));

			DEV_MESSAGE(KERN_ERR, device, "%s",
				    "End of channel program:");
			hex_dump_memory(device, lcqr->cpaddr + cplength - 10,
					10*sizeof(struct ccw1));
		} else {	/* log the whole CP */
			DEV_MESSAGE(KERN_ERR, device, "%s",
				    "Channel program (complete):");
			hex_dump_memory(device, lcqr->cpaddr,
					cplength*sizeof(struct ccw1));
		}

		if (lcqr != cqr)
			continue;

		/*
		 * Log bytes arround failed CCW but only if we did
		 * not log the whole CP of the CCW is outside the
		 * logged CP. 
		 */
		if (cplength > 40 ||
		    ((addr_t) cpa < (addr_t) lcqr->cpaddr &&
		     (addr_t) cpa > (addr_t) (lcqr->cpaddr + cplength + 4))) {
			
			DEV_MESSAGE(KERN_ERR, device,
				    "Failed CCW (%p) (area):",
				    (void *) (long) cpa);
			hex_dump_memory(device, cqr->cpaddr - 10,
					20*sizeof(struct ccw1));
		}
	}

}				/* end log_erp_chain */

EXPORT_SYMBOL(dasd_default_erp_action);
EXPORT_SYMBOL(dasd_default_erp_postaction);
EXPORT_SYMBOL(dasd_alloc_erp_request);
EXPORT_SYMBOL(dasd_free_erp_request);
EXPORT_SYMBOL(dasd_log_sense);
EXPORT_SYMBOL(dasd_log_ccw);
