Re: Fw: 2.6.12-mm2: 3ware SATA RAID inaccessible

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Jun 28 2005, Nick Orlov wrote:
> On Mon, Jun 27, 2005 at 11:05:41PM -0500, James Bottomley wrote:
> > On Mon, 2005-06-27 at 22:08 -0400, Nick Orlov wrote:
> > > EIP is at tw_scsiop_mode_sense_complete+0xc7/0xe0
> > 
> > OK, so it got to the mode sense.  What happened to the preceeding
> > INQUIRY?  Did it produce correct values or did it trip the error
> > condition?
> 
> Hard to say. Kernel panics right after the small pause during detection.
> And scroll back does not work. I don't really know what it prints before.

Try this variant, fixes the mapping type and kunmap_atomic().

diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c
--- a/drivers/scsi/3w-xxxx.c
+++ b/drivers/scsi/3w-xxxx.c
@@ -1499,22 +1499,50 @@ static int tw_scsiop_inquiry(TW_Device_E
 	return 0;
 } /* End tw_scsiop_inquiry() */
 
+static void *tw_map_internal(TW_Device_Extension *tw_dev, int request_id,
+			     int *len)
+{
+	struct scsi_cmnd *cmd = tw_dev->srb[request_id];
+	void *buf;
+
+	if (cmd->use_sg) {
+		struct scatterlist *sg =
+			(struct scatterlist *)cmd->request_buffer;
+		buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
+		*len = sg->length;
+	} else {
+		buf = cmd->request_buffer;
+		*len = cmd->request_bufflen;
+	}
+	return buf;
+}
+
+static void tw_unmap_internal(TW_Device_Extension *tw_dev, char *ptr,
+			      int request_id)
+{
+	struct scsi_cmnd *cmd = tw_dev->srb[request_id];
+
+	if (cmd->use_sg)
+		kunmap_atomic(ptr, KM_IRQ0);
+}
+
 /* This function is called by the isr to complete an inquiry command */
 static int tw_scsiop_inquiry_complete(TW_Device_Extension *tw_dev, int request_id)
 {
 	unsigned char *is_unit_present;
 	unsigned char *request_buffer;
+	int len;
 	TW_Param *param;
 
 	dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_inquiry_complete()\n");
 
 	/* Fill request buffer */
-	if (tw_dev->srb[request_id]->request_buffer == NULL) {
+	request_buffer = tw_map_internal(tw_dev, request_id, &len);
+	if (request_buffer == NULL || len < 36) {
 		printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry_complete(): Request buffer NULL.\n");
 		return 1;
 	}
-	request_buffer = tw_dev->srb[request_id]->request_buffer;
-	memset(request_buffer, 0, tw_dev->srb[request_id]->request_bufflen);
+	memset(request_buffer, 0, len);
 	request_buffer[0] = TYPE_DISK; /* Peripheral device type */
 	request_buffer[1] = 0;	       /* Device type modifier */
 	request_buffer[2] = 0;	       /* No ansi/iso compliance */
@@ -1522,6 +1550,7 @@ static int tw_scsiop_inquiry_complete(TW
 	memcpy(&request_buffer[8], "3ware   ", 8);	 /* Vendor ID */
 	sprintf(&request_buffer[16], "Logical Disk %-2d ", tw_dev->srb[request_id]->device->id);
 	memcpy(&request_buffer[32], TW_DRIVER_VERSION, 3);
+	tw_unmap_internal(tw_dev, request_buffer, request_id);
 
 	param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
 	if (param == NULL) {
@@ -1613,6 +1642,7 @@ static int tw_scsiop_mode_sense_complete
 	TW_Param *param;
 	unsigned char *flags;
 	unsigned char *request_buffer;
+	int len;
 
 	dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_mode_sense_complete()\n");
 
@@ -1622,8 +1652,9 @@ static int tw_scsiop_mode_sense_complete
 		return 1;
 	}
 	flags = (char *)&(param->data[0]);
-	request_buffer = tw_dev->srb[request_id]->buffer;
-	memset(request_buffer, 0, tw_dev->srb[request_id]->request_bufflen);
+	request_buffer = tw_map_internal(tw_dev, request_id, &len);
+	memset(request_buffer, 0, len);
+	BUG_ON(len < 7);
 
 	request_buffer[0] = 0xf;        /* mode data length */
 	request_buffer[1] = 0;          /* default medium type */
@@ -1635,6 +1666,7 @@ static int tw_scsiop_mode_sense_complete
 		request_buffer[6] = 0x4;        /* WCE on */
 	else
 		request_buffer[6] = 0x0;        /* WCE off */
+	tw_unmap_internal(tw_dev, request_buffer, request_id);
 
 	return 0;
 } /* End tw_scsiop_mode_sense_complete() */
@@ -1703,15 +1735,16 @@ static int tw_scsiop_read_capacity_compl
 	u32 capacity;
 	char *buff;
 	TW_Param *param;
+	int len;
 
 	dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity_complete()\n");
 
-	buff = tw_dev->srb[request_id]->request_buffer;
-	if (buff == NULL) {
+	buff = tw_map_internal(tw_dev, request_id, &len);
+	if (buff == NULL || len < 8) {
 		printk(KERN_WARNING "3w-xxxx: tw_scsiop_read_capacity_complete(): Request buffer NULL.\n");
 		return 1;
 	}
-	memset(buff, 0, tw_dev->srb[request_id]->request_bufflen);
+	memset(buff, 0, len);
 	param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
 	if (param == NULL) {
 		printk(KERN_WARNING "3w-xxxx: tw_scsiop_read_capacity_complete(): Bad alignment virtual address.\n");
@@ -1739,6 +1772,8 @@ static int tw_scsiop_read_capacity_compl
 	buff[6] = (TW_BLOCK_SIZE >> 8) & 0xff;
 	buff[7] = TW_BLOCK_SIZE & 0xff;
 
+	tw_unmap_internal(tw_dev, buff, request_id);
+
 	return 0;
 } /* End tw_scsiop_read_capacity_complete() */
 

-- 
Jens Axboe

-
: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux