
#include <sys/types.h>
#include <sys/fcntl.h>
#include <errno.h>
#include <sys/scsi/scsi.h>

char device[128] = "/dev/rdsk/";
char buf[1024];
char cdb[128];
struct uscsi_cmd ucmd;
int status;
struct mode_caching *mode_caching_page;

main(int argc, char *argv[])
{
	int fd, ret, data_length, i;
	int enable;

	if (argc < 3) {
		printf("Usage %s device enable|disable \n", argv[0]);
		exit(1);
	}
	strcat(device, argv[1]);

	if ((fd = open(device, O_RDWR)) < 0) {
		perror("open ");
		exit (1);
	}

	if (!strcmp(argv[2], "enable") || !strcmp(argv[2], "ENABLE")) {
		printf("Enabling Write Cache\n");
		enable = 1;
	} else {
	   if (!strcmp(argv[2], "disable") || ! (strcmp(argv[2], "DISABLE"))) {
		printf("Disabling WRITE cache\n");
		enable = 0;
	   } else {
		  printf("Usage %s device enable|disable \n", argv[0]);
               	  exit(1); 
        	}
	}



	data_length = MODE_PARAM_LENGTH + 20; /*sizeof (struct mode_caching);*/
	mode_caching_page = (struct mode_caching *)&buf[MODE_PARAM_LENGTH];

	cdb[0] = 0x1A;		/* OP code */
	cdb[1] = 0x0;		/* lun | DBD */
	cdb[2] = 0x8;		/* Page code */
	cdb[3] = 0x0;		/* Reserved */
	cdb[4] = data_length;	/* Allocation Length */
	cdb[5] = 0x0;		/* controll */


	ucmd.uscsi_cdb = (caddr_t)cdb;
	ucmd.uscsi_cdblen = 0x6;
	ucmd.uscsi_bufaddr = (caddr_t)buf;
	ucmd.uscsi_buflen = data_length;
	ucmd.uscsi_flags = USCSI_DIAGNOSE | USCSI_READ;
	status = ioctl(fd, USCSICMD, &ucmd);
	if (status || ucmd.uscsi_status) {
		printf("command 0x%02x failed: %d - %d\n",
			ucmd.uscsi_cdb[0], status, ucmd.uscsi_status);
	}


#if 0
	for (i=0; i<data_length; i++)
		printf("%x ", buf[i]);
#endif

	printf("\nwrite caching %s\n", 
			mode_caching_page->wce? "already enabled":"disabled");

	if (enable == 0) {
		mode_caching_page->wce = 0;
	} else {
		mode_caching_page->wce =1;
	}


	buf[0] = 0x0;
	buf[1] = 0x0;
	buf[2] = 0x0;

	mode_caching_page->mode_page.code = 0x8;
	mode_caching_page->mode_page.ps = 0;
	mode_caching_page->mode_page.length = 0x12;/* 0xC;*/


	cdb[0] = 0x15;		/* OP code */
	cdb[1] = 0x11;		/* lun | PF | SP */
	cdb[2] = 0x0;		/* Page code */
	cdb[3] = 0x0;		/* Reserved */
	cdb[4] = data_length;	/* Allocation Length */
	cdb[5] = 0x0;		/* controll */

	ucmd.uscsi_cdb = (caddr_t)cdb;
	ucmd.uscsi_cdblen = 0x6;
	ucmd.uscsi_bufaddr = (caddr_t)buf;
	ucmd.uscsi_buflen = data_length;
	ucmd.uscsi_flags = USCSI_DIAGNOSE | USCSI_WRITE;
	status = ioctl(fd, USCSICMD, &ucmd);
	if (status || ucmd.uscsi_status) {
		printf("command 0x%02x failed: %d - %d\n",
			ucmd.uscsi_cdb[0], status, ucmd.uscsi_status);
	}

#if 0
	printf("Data After Mode Select \n");
	for (i=0; i<data_length; i++)
		printf("%x ", buf[i]);
	printf("\nwrite caching %x\n", mode_caching_page->wce);
#endif


	cdb[0] = 0x1A;		/* OP code */
	cdb[1] = 0x0;		/* lun | DBD */
	cdb[2] = 0x8;		/* Page code */
	cdb[3] = 0x0;		/* Reserved */
	cdb[4] = data_length;	/* Allocation Length */
	cdb[5] = 0x0;		/* controll */


	ucmd.uscsi_cdb = (caddr_t)cdb;
	ucmd.uscsi_cdblen = 0x6;
	ucmd.uscsi_bufaddr = (caddr_t)buf;
	ucmd.uscsi_buflen = data_length;
	ucmd.uscsi_flags = USCSI_DIAGNOSE | USCSI_READ;
	status = ioctl(fd, USCSICMD, &ucmd);
	if (status || ucmd.uscsi_status) {
		printf("command 0x%02x failed: %d - %d\n",
			ucmd.uscsi_cdb[0], status, ucmd.uscsi_status);
	}


#if 0
	printf("After Mode Sense\n");
	for (i=0; i<data_length; i++)
		printf("%x ", buf[i]);
#endif

	printf("\nwrite caching %s\n", 
		(mode_caching_page->wce)? "enabled": "disabled");

	close(fd);
}
