/*
 * This file is part of the UCB release of Plan 9. It is subject to the license
 * terms in the LICENSE file found in the top-level directory of this
 * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
 * part of the UCB release of Plan 9, including this file, may be copied,
 * modified, propagated, or distributed except according to the terms contained
 * in the LICENSE file.
 */

#include <vfs.h>

#include <assert.h>
#include <cpio.h>
#include <error.h>
#include <net/ip.h>
#include <kfs.h>
#include <kmalloc.h>
#include <kref.h>
#include <pmap.h>
#include <sd.h>
#include <slab.h>
#include <smp.h>
#include <stdio.h>
#include <string.h>

static int scsitest(struct sdreq *r)
{
	r->write = 0;
	memset(r->cmd, 0, sizeof(r->cmd));
	r->cmd[1] = r->lun << 5;
	r->clen = 6;
	r->data = NULL;
	r->dlen = 0;
	r->flags = 0;

	r->status = ~0;

	return r->unit->dev->ifc->rio(r);
}

int scsiverify(struct sdunit *unit)
{
	struct sdreq *r;
	int i, status;
	uint8_t *inquiry;

	r = kzmalloc(sizeof(struct sdreq), 0);
	if (r == NULL)
		return 0;
	inquiry = kzmalloc(sizeof(unit->inquiry), MEM_WAIT);
	if (inquiry == NULL) {
		kfree(r);
		return 0;
	}
	r->unit = unit;
	r->lun = 0; /* ??? */

	memset(unit->inquiry, 0, sizeof(unit->inquiry));
	r->write = 0;
	r->cmd[0] = 0x12;
	r->cmd[1] = r->lun << 5;
	r->cmd[4] = sizeof(unit->inquiry) - 1;
	r->clen = 6;
	r->data = inquiry;
	r->dlen = sizeof(unit->inquiry) - 1;
	r->flags = 0;

	r->status = ~0;
	if (unit->dev->ifc->rio(r) != SDok) {
		kfree(r);
		return 0;
	}
	memmove(unit->inquiry, inquiry, r->dlen);
	kfree(inquiry);

	for (i = 0; i < 3; i++) {
		while ((status = scsitest(r)) == SDbusy)
			;
		if (status == SDok || status != SDcheck)
			break;
		if (!(r->flags & SDvalidsense))
			break;
		if ((r->sense[2] & 0x0F) != 0x02)
			continue;

		/*
		 * Unit is 'not ready'.
		 * If it is in the process of becoming ready or needs
		 * an initialising command, set status so it will be spun-up
		 * below.
		 * If there's no medium, that's OK too, but don't
		 * try to spin it up.
		 */
		if (r->sense[12] == 0x04) {
			if (r->sense[13] == 0x02 || r->sense[13] == 0x01) {
				status = SDok;
				break;
			}
		}
		if (r->sense[12] == 0x3A)
			break;
	}

	if (status == SDok) {
		/*
		 * Try to ensure a direct-access device is spinning.
		 * Don't wait for completion, ignore the result.
		 */
		if ((unit->inquiry[0] & SDinq0periphtype) == SDperdisk) {
			memset(r->cmd, 0, sizeof(r->cmd));
			r->write = 0;
			r->cmd[0] = 0x1B;
			r->cmd[1] = (r->lun << 5) | 0x01;
			r->cmd[4] = 1;
			r->clen = 6;
			r->data = NULL;
			r->dlen = 0;
			r->flags = 0;

			r->status = ~0;
			unit->dev->ifc->rio(r);
		}
	}
	kfree(r);

	if (status == SDok || status == SDcheck)
		return 1;
	return 0;
}

static int scsirio(struct sdreq *r)
{
	ERRSTACK(1);
	/*
	 * Perform an I/O request, returning
	 *	-1	failure
	 *	 0	ok
	 *	 1	no medium present
	 *	 2	retry
	 * The contents of r may be altered so the
	 * caller should re-initialise if necesary.
	 */
	r->status = ~0;
	switch (r->unit->dev->ifc->rio(r)) {
	default:
		break;
	case SDcheck:
		if (!(r->flags & SDvalidsense))
			break;
		switch (r->sense[2] & 0x0F) {
		case 0x00: /* no sense */
		case 0x01: /* recovered error */
			return 2;
		case 0x06: /* check condition */
			/*
			 * 0x28 - not ready to ready transition,
			 *	  medium may have changed.
			 * 0x29 - power on or some type of reset.
			 */
			if (r->sense[12] == 0x28 && r->sense[13] == 0)
				return 2;
			if (r->sense[12] == 0x29)
				return 2;
			break;
		case 0x02: /* not ready */
			/*
			 * If no medium present, bail out.
			 * If unit is becoming ready, rather than not
			 * not ready, wait a little then poke it again. 				 */
			if (r->sense[12] == 0x3A)
				break;
			if (r->sense[12] != 0x04 || r->sense[13] != 0x01)
				break;

			while (waserror())
				;
			kthread_usleep(500 * 1000);
			poperror();
			scsitest(r);
			return 2;
		default:
			break;
		}
		break;
	case SDok:
		return 0;
	}
	return -1;
}

int scsionline(struct sdunit *unit)
{
	struct sdreq *r;
	uint8_t *p;
	int ok, retries;

	r = kzmalloc(sizeof(struct sdreq), 0);
	if (r == NULL)
		return 0;
	p = kzmalloc(8, 0);
	if (p == NULL) {
		kfree(r);
		return 0;
	}

	ok = 0;

	r->unit = unit;
	r->lun = 0; /* ??? */
	for (retries = 0; retries < 10; retries++) {
		/*
		 * Read-capacity is mandatory for DA, WORM, CD-ROM and
		 * MO. It may return 'not ready' if type DA is not
		 * spun up, type MO or type CD-ROM are not loaded or just
		 * plain slow getting their act together after a reset.
		 */
		r->write = 0;
		memset(r->cmd, 0, sizeof(r->cmd));
		r->cmd[0] = 0x25;
		r->cmd[1] = r->lun << 5;
		r->clen = 10;
		r->data = p;
		r->dlen = 8;
		r->flags = 0;

		r->status = ~0;
		switch (scsirio(r)) {
		default:
			break;
		case 0:
			unit->sectors = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
			unit->secsize = (p[4] << 24) | (p[5] << 16) | (p[6] << 8) | p[7];

			/*
			 * Some ATAPI CD readers lie about the block size.
			 * Since we don't read audio via this interface
			 * it's okay to always fudge this.
			 */
			if (unit->secsize == 2352)
				unit->secsize = 2048;
			/*
			 * Devices with removable media may return 0 sectors
			 * when they have empty media (e.g. sata dvd writers);
			 * if so, keep the count zero.
			 *
			 * Read-capacity returns the LBA of the last sector,
			 * therefore the number of sectors must be incremented.
			 */
			if (unit->sectors != 0)
				unit->sectors++;
			ok = 1;
			break;
		case 1:
			ok = 1;
			break;
		case 2:
			continue;
		}
		break;
	}
	kfree(p);
	kfree(r);

	if (ok)
		return ok + retries;
	else
		return 0;
}

int scsiexec(struct sdunit *unit, int write, uint8_t *cmd, int clen, void *data,
             int *dlen)
{
	struct sdreq *r;
	int status;

	r = kzmalloc(sizeof(struct sdreq), 0);
	if (r == NULL)
		return SDmalloc;
	r->unit = unit;
	r->lun = cmd[1] >> 5; /* ??? */
	r->write = write;
	memmove(r->cmd, cmd, clen);
	r->clen = clen;
	r->data = data;
	if (dlen)
		r->dlen = *dlen;
	r->flags = 0;

	r->status = ~0;

	/*
	 * Call the device-specific I/O routine.
	 * There should be no calls to 'error()' below this
	 * which percolate back up.
	 */
	switch (status = unit->dev->ifc->rio(r)) {
	case SDok:
		if (dlen)
			*dlen = r->rlen;
	/*FALLTHROUGH*/
	case SDcheck:
	/*FALLTHROUGH*/
	default:
		/*
		 * It's more complicated than this. There are conditions
		 * which are 'ok' but for which the returned status code
		 * is not 'SDok'.
		 * Also, not all conditions require a reqsense, might
		 * need to do a reqsense here and make it available to the
		 * caller somehow.
		 *
		 * Mañana.
		 */
		break;
	}
	kfree(r);

	return status;
}

static void scsifmt10(struct sdreq *r, int write, int lun, uint32_t nb,
                      uint64_t bno)
{
	uint8_t *c;

	c = r->cmd;
	if (write == 0)
		c[0] = 0x28;
	else
		c[0] = 0x2A;
	c[1] = lun << 5;
	c[2] = bno >> 24;
	c[3] = bno >> 16;
	c[4] = bno >> 8;
	c[5] = bno;
	c[6] = 0;
	c[7] = nb >> 8;
	c[8] = nb;
	c[9] = 0;

	r->clen = 10;
}

static void scsifmt16(struct sdreq *r, int write, int lun, uint32_t nb,
                      uint64_t bno)
{
	uint8_t *c;

	c = r->cmd;
	if (write == 0)
		c[0] = 0x88;
	else
		c[0] = 0x8A;
	c[1] = lun << 5; /* so wrong */
	c[2] = bno >> 56;
	c[3] = bno >> 48;
	c[4] = bno >> 40;
	c[5] = bno >> 32;
	c[6] = bno >> 24;
	c[7] = bno >> 16;
	c[8] = bno >> 8;
	c[9] = bno;
	c[10] = nb >> 24;
	c[11] = nb >> 16;
	c[12] = nb >> 8;
	c[13] = nb;
	c[14] = 0;
	c[15] = 0;

	r->clen = 16;
}

int32_t scsibio(struct sdunit *unit, int lun, int write, void *data, int32_t nb,
                uint64_t bno)
{
	struct sdreq *r;
	int32_t rlen;

	r = kzmalloc(sizeof(struct sdreq), 0);
	if (r == NULL)
		error(ENOMEM, "scsibio: can't allocate %d bytes", sizeof(*r));
	r->unit = unit;
	r->lun = lun;
again:
	r->write = write;
	if (bno >= (1ULL << 32))
		scsifmt16(r, write, lun, nb, bno);
	else
		scsifmt10(r, write, lun, nb, bno);
	r->data = data;
	r->dlen = nb * unit->secsize;
	r->flags = 0;

	r->status = ~0;
	switch (scsirio(r)) {
	default:
		rlen = -1;
		break;
	case 0:
		rlen = r->rlen;
		break;
	case 2:
		rlen = -1;
		if (!(r->flags & SDvalidsense))
			break;
		switch (r->sense[2] & 0x0F) {
		default:
			break;
		case 0x01: /* recovered error */
			printd("%s: recovered error at sector %llu\n", unit->SDperm.name,
			       bno);
			rlen = r->rlen;
			break;
		case 0x06: /* check condition */
			/*
			 * Check for a removeable media change.
			 * If so, mark it by zapping the geometry info
			 * to force an online request.
			 */
			if (r->sense[12] != 0x28 || r->sense[13] != 0)
				break;
			if (unit->inquiry[1] & SDinq1removable)
				unit->sectors = 0;
			break;
		case 0x02: /* not ready */
			/*
			 * If unit is becoming ready,
			 * rather than not not ready, try again.
			 */
			if (r->sense[12] == 0x04 && r->sense[13] == 0x01)
				goto again;
			break;
		}
		break;
	}
	kfree(r);

	return rlen;
}
