Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3b2946cc authored by Mark Haverkamp's avatar Mark Haverkamp Committed by James Bottomley
Browse files

[SCSI] aacraid: Fix aacraid probe breakage (updated)



This patch fixes the bad assumption of the aacraid driver with use_sg.
I used the 3w-xxxx driver fix as a guide for this.

Signed-off-by: default avatarMark Haverkamp <markh@osdl.org>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent ebd8bb76
Loading
Loading
Loading
Loading
+53 −26
Original line number Diff line number Diff line
@@ -349,6 +349,27 @@ static void aac_io_done(struct scsi_cmnd * scsicmd)
	spin_unlock_irqrestore(host->host_lock, cpu_flags);
}

static void aac_internal_transfer(struct scsi_cmnd *scsicmd, void *data, unsigned int offset, unsigned int len)
{
	void *buf;
	unsigned int transfer_len;
	struct scatterlist *sg = scsicmd->request_buffer;

	if (scsicmd->use_sg) {
		buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
		transfer_len = min(sg->length, len + offset);
	} else {
		buf = scsicmd->request_buffer;
		transfer_len = min(scsicmd->request_bufflen, len + offset);
	}

	memcpy(buf + offset, data, transfer_len - offset);

	if (scsicmd->use_sg) 
		kunmap_atomic(buf - sg->offset, KM_IRQ0);

}

static void get_container_name_callback(void *context, struct fib * fibptr)
{
	struct aac_get_name_resp * get_name_reply;
@@ -364,18 +385,22 @@ static void get_container_name_callback(void *context, struct fib * fibptr)
	/* Failure is irrelevant, using default value instead */
	if ((le32_to_cpu(get_name_reply->status) == CT_OK)
	 && (get_name_reply->data[0] != '\0')) {
		int    count;
		char * dp;
		char *sp = get_name_reply->data;
		sp[sizeof(((struct aac_get_name_resp *)NULL)->data)-1] = '\0';
		while (*sp == ' ')
			++sp;
		count = sizeof(((struct inquiry_data *)NULL)->inqd_pid);
		dp = ((struct inquiry_data *)scsicmd->request_buffer)->inqd_pid;
		if (*sp) do {
		if (*sp) {
			char d[sizeof(((struct inquiry_data *)NULL)->inqd_pid)];
			int count = sizeof(d);
			char *dp = d;
			do {
				*dp++ = (*sp) ? *sp++ : ' ';
			} while (--count > 0);
			aac_internal_transfer(scsicmd, d, 
			  offsetof(struct inquiry_data, inqd_pid), sizeof(d));
		}
	}

	scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;

	fib_complete(fibptr);
@@ -1344,44 +1369,45 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
	switch (scsicmd->cmnd[0]) {
	case INQUIRY:
	{
		struct inquiry_data *inq_data_ptr;
		struct inquiry_data inq_data;

		dprintk((KERN_DEBUG "INQUIRY command, ID: %d.\n", scsicmd->device->id));
		inq_data_ptr = (struct inquiry_data *)scsicmd->request_buffer;
		memset(inq_data_ptr, 0, sizeof (struct inquiry_data));
		memset(&inq_data, 0, sizeof (struct inquiry_data));

		inq_data_ptr->inqd_ver = 2;	/* claim compliance to SCSI-2 */
		inq_data_ptr->inqd_dtq = 0x80;	/* set RMB bit to one indicating that the medium is removable */
		inq_data_ptr->inqd_rdf = 2;	/* A response data format value of two indicates that the data shall be in the format specified in SCSI-2 */
		inq_data_ptr->inqd_len = 31;
		inq_data.inqd_ver = 2;	/* claim compliance to SCSI-2 */
		inq_data.inqd_dtq = 0x80;	/* set RMB bit to one indicating that the medium is removable */
		inq_data.inqd_rdf = 2;	/* A response data format value of two indicates that the data shall be in the format specified in SCSI-2 */
		inq_data.inqd_len = 31;
		/*Format for "pad2" is  RelAdr | WBus32 | WBus16 |  Sync  | Linked |Reserved| CmdQue | SftRe */
		inq_data_ptr->inqd_pad2= 0x32 ;	 /*WBus16|Sync|CmdQue */
		inq_data.inqd_pad2= 0x32 ;	 /*WBus16|Sync|CmdQue */
		/*
		 *	Set the Vendor, Product, and Revision Level
		 *	see: <vendor>.c i.e. aac.c
		 */
		if (scsicmd->device->id == host->this_id) {
			setinqstr(cardtype, (void *) (inq_data_ptr->inqd_vid), (sizeof(container_types)/sizeof(char *)));
			inq_data_ptr->inqd_pdt = INQD_PDT_PROC;	/* Processor device */
			setinqstr(cardtype, (void *) (inq_data.inqd_vid), (sizeof(container_types)/sizeof(char *)));
			inq_data.inqd_pdt = INQD_PDT_PROC;	/* Processor device */
			aac_internal_transfer(scsicmd, &inq_data, 0, sizeof(inq_data));
			scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
			scsicmd->scsi_done(scsicmd);
			return 0;
		}
		setinqstr(cardtype, (void *) (inq_data_ptr->inqd_vid), fsa_dev_ptr[cid].type);
		inq_data_ptr->inqd_pdt = INQD_PDT_DA;	/* Direct/random access device */
		setinqstr(cardtype, (void *) (inq_data.inqd_vid), fsa_dev_ptr[cid].type);
		inq_data.inqd_pdt = INQD_PDT_DA;	/* Direct/random access device */
		aac_internal_transfer(scsicmd, &inq_data, 0, sizeof(inq_data));
		return aac_get_container_name(scsicmd, cid);
	}
	case READ_CAPACITY:
	{
		u32 capacity;
		char *cp;
		char cp[8];

		dprintk((KERN_DEBUG "READ CAPACITY command.\n"));
		if (fsa_dev_ptr[cid].size <= 0x100000000LL)
			capacity = fsa_dev_ptr[cid].size - 1;
		else
			capacity = (u32)-1;
		cp = scsicmd->request_buffer;

		cp[0] = (capacity >> 24) & 0xff;
		cp[1] = (capacity >> 16) & 0xff;
		cp[2] = (capacity >> 8) & 0xff;
@@ -1390,6 +1416,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
		cp[5] = 0;
		cp[6] = 2;
		cp[7] = 0;
		aac_internal_transfer(scsicmd, cp, 0, sizeof(cp));

		scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
		scsicmd->scsi_done(scsicmd);
@@ -1399,15 +1426,15 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)

	case MODE_SENSE:
	{
		char *mode_buf;
		char mode_buf[4];

		dprintk((KERN_DEBUG "MODE SENSE command.\n"));
		mode_buf = scsicmd->request_buffer;
		mode_buf[0] = 3;	/* Mode data length */
		mode_buf[1] = 0;	/* Medium type - default */
		mode_buf[2] = 0;	/* Device-specific param, bit 8: 0/1 = write enabled/protected */
		mode_buf[3] = 0;	/* Block descriptor length */

		aac_internal_transfer(scsicmd, mode_buf, 0, sizeof(mode_buf));
		scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
		scsicmd->scsi_done(scsicmd);

@@ -1415,10 +1442,9 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
	}
	case MODE_SENSE_10:
	{
		char *mode_buf;
		char mode_buf[8];

		dprintk((KERN_DEBUG "MODE SENSE 10 byte command.\n"));
		mode_buf = scsicmd->request_buffer;
		mode_buf[0] = 0;	/* Mode data length (MSB) */
		mode_buf[1] = 6;	/* Mode data length (LSB) */
		mode_buf[2] = 0;	/* Medium type - default */
@@ -1427,6 +1453,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
		mode_buf[5] = 0;	/* reserved */
		mode_buf[6] = 0;	/* Block descriptor length (MSB) */
		mode_buf[7] = 0;	/* Block descriptor length (LSB) */
		aac_internal_transfer(scsicmd, mode_buf, 0, sizeof(mode_buf));

		scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
		scsicmd->scsi_done(scsicmd);