/*
 * Transport for the Sandisk SDDR-55
 */
int sddr55_transport(Scsi_Cmnd *srb, struct us_data *us)
{
	int result;
	int i;
	unsigned char inquiry_response[36] = {
		0x00, 0x80, 0x00, 0x02, 0x1F, 0x00, 0x00, 0x00
	};
	unsigned char mode_page_01[16] = { // write-protected for now
		0x03, 0x00, 0x80, 0x00,
		0x01, 0x0A,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
	};
	unsigned char *ptr;
	unsigned long capacity;
	unsigned int lba;
	unsigned int pba;
	unsigned int page;
	unsigned short pages;
	struct sddr55_card_info *info;

	if (!us->extra) {
		us->extra = kmalloc(
			sizeof(struct sddr55_card_info), GFP_NOIO);
		if (!us->extra)
			return USB_STOR_TRANSPORT_ERROR;
		memset(us->extra, 0, sizeof(struct sddr55_card_info));
		us->extra_destructor = sddr55_card_info_destructor;
	}

	info = (struct sddr55_card_info *)(us->extra);

	ptr = (unsigned char *)srb->request_buffer;

	if (srb->cmnd[0] == REQUEST_SENSE) {
		i = srb->cmnd[4];

		if (i > sizeof info->sense_data)
			i = sizeof info->sense_data;


		US_DEBUGP("SDDR55: request sense %02x/%02x/%02x\n", info->sense_data[2], info->sense_data[12], info->sense_data[13]);

		info->sense_data[0] = 0x70;
		info->sense_data[7] = 10;

		memcpy (ptr, info->sense_data, i);
		memset (info->sense_data, 0, sizeof info->sense_data);

		return USB_STOR_TRANSPORT_GOOD;
	}

	memset (info->sense_data, 0, sizeof info->sense_data);

	/* Dummy up a response for INQUIRY since SDDR55 doesn't
	   respond to INQUIRY commands */

	if (srb->cmnd[0] == INQUIRY) {
		memset(inquiry_response+8, 0, 28);
		fill_inquiry_response(us, inquiry_response, 36);
		return USB_STOR_TRANSPORT_GOOD;
	}

	/* only check card status if the map isn't allocated, ie no card seen yet
	 * or if it's been over half a second since we last accessed it
	 */
	if (info->lba_to_pba == NULL || time_after(jiffies, info->last_access + HZ/2)) {

		/* check to see if a card is fitted */
		result = sddr55_status (us);
		if (result) {
			result = sddr55_status (us);
			if (!result) {
			set_sense_info (6, 0x28, 0);	/* new media, set unit attention, not ready to ready */
			}
			return USB_STOR_TRANSPORT_FAILED;
		}
	}

	/* if we detected a problem with the map when writing, don't allow any more access */
	if (info->fatal_error) {

		set_sense_info (3, 0x31, 0);
		return USB_STOR_TRANSPORT_FAILED;
	}

	if (srb->cmnd[0] == READ_CAPACITY) {

		capacity = sddr55_get_capacity(us);

		if (!capacity) {
			set_sense_info (3, 0x30, 0);	/* incompatible medium */
			return USB_STOR_TRANSPORT_FAILED;
		}

		info->capacity = capacity;

                /* figure out the maximum logical block number, allowing for the fact
                 * that only 250 out of every 256 are used */
		info->max_log_blks = ((info->capacity >> (info->pageshift + info->blockshift)) / 256) * 250;

		/* Last page in the card, adjust as we only use 250 out of every 256 pages */
		capacity = (capacity / 256) * 250;

		capacity /= PAGESIZE;
		capacity--;

		ptr[0] = MSB_of(capacity>>16);
		ptr[1] = LSB_of(capacity>>16);
		ptr[2] = MSB_of(capacity&0xFFFF);
		ptr[3] = LSB_of(capacity&0xFFFF);

		// The page size

		ptr[4] = MSB_of(PAGESIZE>>16);
		ptr[5] = LSB_of(PAGESIZE>>16);
		ptr[6] = MSB_of(PAGESIZE&0xFFFF);
		ptr[7] = LSB_of(PAGESIZE&0xFFFF);

		sddr55_read_map(us);

		return USB_STOR_TRANSPORT_GOOD;
	}
Example #2
0
/*
 * Transport for the Sandisk SDDR-55
 */
static int sddr55_transport(struct scsi_cmnd *srb, struct us_data *us)
{
	int result;
	static unsigned char inquiry_response[8] = {
		0x00, 0x80, 0x00, 0x02, 0x1F, 0x00, 0x00, 0x00
	};
 	// write-protected for now, no block descriptor support
	static unsigned char mode_page_01[20] = {
		0x0, 0x12, 0x00, 0x80, 0x0, 0x0, 0x0, 0x0,
		0x01, 0x0A,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
	};
	unsigned char *ptr = us->iobuf;
	unsigned long capacity;
	unsigned int lba;
	unsigned int pba;
	unsigned int page;
	unsigned short pages;
	struct sddr55_card_info *info;

	if (!us->extra) {
		us->extra = kzalloc(
			sizeof(struct sddr55_card_info), GFP_NOIO);
		if (!us->extra)
			return USB_STOR_TRANSPORT_ERROR;
		us->extra_destructor = sddr55_card_info_destructor;
	}

	info = (struct sddr55_card_info *)(us->extra);

	if (srb->cmnd[0] == REQUEST_SENSE) {
		usb_stor_dbg(us, "request sense %02x/%02x/%02x\n",
			     info->sense_data[2],
			     info->sense_data[12],
			     info->sense_data[13]);

		memcpy (ptr, info->sense_data, sizeof info->sense_data);
		ptr[0] = 0x70;
		ptr[7] = 11;
		usb_stor_set_xfer_buf (ptr, sizeof info->sense_data, srb);
		memset (info->sense_data, 0, sizeof info->sense_data);

		return USB_STOR_TRANSPORT_GOOD;
	}

	memset (info->sense_data, 0, sizeof info->sense_data);

	/*
	 * Dummy up a response for INQUIRY since SDDR55 doesn't
	 * respond to INQUIRY commands
	 */

	if (srb->cmnd[0] == INQUIRY) {
		memcpy(ptr, inquiry_response, 8);
		fill_inquiry_response(us, ptr, 36);
		return USB_STOR_TRANSPORT_GOOD;
	}

	/*
	 * only check card status if the map isn't allocated, ie no card seen yet
	 * or if it's been over half a second since we last accessed it
	 */
	if (info->lba_to_pba == NULL || time_after(jiffies, info->last_access + HZ/2)) {

		/* check to see if a card is fitted */
		result = sddr55_status (us);
		if (result) {
			result = sddr55_status (us);
			if (!result) {
			set_sense_info (6, 0x28, 0);	/* new media, set unit attention, not ready to ready */
			}
			return USB_STOR_TRANSPORT_FAILED;
		}
	}

	/*
	 * if we detected a problem with the map when writing,
	 * don't allow any more access
	 */
	if (info->fatal_error) {

		set_sense_info (3, 0x31, 0);
		return USB_STOR_TRANSPORT_FAILED;
	}

	if (srb->cmnd[0] == READ_CAPACITY) {

		capacity = sddr55_get_capacity(us);

		if (!capacity) {
			set_sense_info (3, 0x30, 0); /* incompatible medium */
			return USB_STOR_TRANSPORT_FAILED;
		}

		info->capacity = capacity;

		/*
		 * figure out the maximum logical block number, allowing for
		 * the fact that only 250 out of every 256 are used
		 */
		info->max_log_blks = ((info->capacity >> (info->pageshift + info->blockshift)) / 256) * 250;

		/*
		 * Last page in the card, adjust as we only use 250 out of
		 * every 256 pages
		 */
		capacity = (capacity / 256) * 250;

		capacity /= PAGESIZE;
		capacity--;

		((__be32 *) ptr)[0] = cpu_to_be32(capacity);
		((__be32 *) ptr)[1] = cpu_to_be32(PAGESIZE);
		usb_stor_set_xfer_buf(ptr, 8, srb);

		sddr55_read_map(us);

		return USB_STOR_TRANSPORT_GOOD;
	}