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

Commit a0899d4d authored by Hans de Goede's avatar Hans de Goede Committed by James Bottomley
Browse files

[SCSI] sd: add fix for devices with last sector access problems



This patch adds a new scsi_device flag (last_sector_bug) for devices
which contain a bug where the device crashes when the last sector is
read in a larger then 1 sector read.

This is for example the case with sdcards in the HP PSC1350 printer
cardreader and in the HP PSC1610 printer cardreader.

Signed-off-by: default avatarHans de Goede <j.w.r.degoede@hhs.nl>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@HansenPartnership.com>
parent b523381e
Loading
Loading
Loading
Loading
+9 −0
Original line number Original line Diff line number Diff line
@@ -395,6 +395,15 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq)
		goto out;
		goto out;
	}
	}


	/*
	 * Some devices (some sdcards for one) don't like it if the
	 * last sector gets read in a larger then 1 sector read.
	 */
	if (unlikely(sdp->last_sector_bug &&
	    rq->nr_sectors > sdp->sector_size / 512 &&
	    block + this_count == get_capacity(disk)))
		this_count -= sdp->sector_size / 512;

	SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt, "block=%llu\n",
	SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt, "block=%llu\n",
					(unsigned long long)block));
					(unsigned long long)block));


+1 −0
Original line number Original line Diff line number Diff line
@@ -139,6 +139,7 @@ struct scsi_device {
	unsigned fix_capacity:1;	/* READ_CAPACITY is too high by 1 */
	unsigned fix_capacity:1;	/* READ_CAPACITY is too high by 1 */
	unsigned guess_capacity:1;	/* READ_CAPACITY might be too high by 1 */
	unsigned guess_capacity:1;	/* READ_CAPACITY might be too high by 1 */
	unsigned retry_hwerror:1;	/* Retry HARDWARE_ERROR */
	unsigned retry_hwerror:1;	/* Retry HARDWARE_ERROR */
	unsigned last_sector_bug:1;	/* Always read last sector in a 1 sector read */


	DECLARE_BITMAP(supported_events, SDEV_EVT_MAXBITS); /* supported events */
	DECLARE_BITMAP(supported_events, SDEV_EVT_MAXBITS); /* supported events */
	struct list_head event_list;	/* asserted events */
	struct list_head event_list;	/* asserted events */