aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2006-05-15 07:57:35 -0400
committerTejun Heo <htejun@gmail.com>2006-05-15 07:57:35 -0400
commitfe635c7e91036282e4fd0cc5b4eebc712e43270d (patch)
tree22054d039df52c19e729f30ceee836936a730ce6
parent158693031d7c58a355ec1852052a4fca75fd3bda (diff)
[PATCH] libata: use preallocated buffers
It's not a very good idea to allocate memory during EH. Use statically allocated buffer for dev->id[] and add 512byte buffer ap->sector_buf. This buffer is owned by EH (or probing) and to be used as temporary buffer for various purposes (IDENTIFY, NCQ log page 10h, PM GSCR block). Signed-off-by: Tejun Heo <htejun@gmail.com>
-rw-r--r--drivers/scsi/libata-core.c32
-rw-r--r--include/linux/libata.h4
2 files changed, 11 insertions, 25 deletions
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index 13bce43f1915..af55861a96e2 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -1099,7 +1099,7 @@ unsigned int ata_pio_need_iordy(const struct ata_device *adev)
1099 * @dev: target device 1099 * @dev: target device
1100 * @p_class: pointer to class of the target device (may be changed) 1100 * @p_class: pointer to class of the target device (may be changed)
1101 * @post_reset: is this read ID post-reset? 1101 * @post_reset: is this read ID post-reset?
1102 * @p_id: read IDENTIFY page (newly allocated) 1102 * @id: buffer to read IDENTIFY data into
1103 * 1103 *
1104 * Read ID data from the specified device. ATA_CMD_ID_ATA is 1104 * Read ID data from the specified device. ATA_CMD_ID_ATA is
1105 * performed on ATA devices and ATA_CMD_ID_ATAPI on ATAPI 1105 * performed on ATA devices and ATA_CMD_ID_ATAPI on ATAPI
@@ -1113,12 +1113,11 @@ unsigned int ata_pio_need_iordy(const struct ata_device *adev)
1113 * 0 on success, -errno otherwise. 1113 * 0 on success, -errno otherwise.
1114 */ 1114 */
1115static int ata_dev_read_id(struct ata_port *ap, struct ata_device *dev, 1115static int ata_dev_read_id(struct ata_port *ap, struct ata_device *dev,
1116 unsigned int *p_class, int post_reset, u16 **p_id) 1116 unsigned int *p_class, int post_reset, u16 *id)
1117{ 1117{
1118 unsigned int class = *p_class; 1118 unsigned int class = *p_class;
1119 struct ata_taskfile tf; 1119 struct ata_taskfile tf;
1120 unsigned int err_mask = 0; 1120 unsigned int err_mask = 0;
1121 u16 *id;
1122 const char *reason; 1121 const char *reason;
1123 int rc; 1122 int rc;
1124 1123
@@ -1126,13 +1125,6 @@ static int ata_dev_read_id(struct ata_port *ap, struct ata_device *dev,
1126 1125
1127 ata_dev_select(ap, dev->devno, 1, 1); /* select device 0/1 */ 1126 ata_dev_select(ap, dev->devno, 1, 1); /* select device 0/1 */
1128 1127
1129 id = kmalloc(sizeof(id[0]) * ATA_ID_WORDS, GFP_KERNEL);
1130 if (id == NULL) {
1131 rc = -ENOMEM;
1132 reason = "out of memory";
1133 goto err_out;
1134 }
1135
1136 retry: 1128 retry:
1137 ata_tf_init(ap, &tf, dev->devno); 1129 ata_tf_init(ap, &tf, dev->devno);
1138 1130
@@ -1194,13 +1186,12 @@ static int ata_dev_read_id(struct ata_port *ap, struct ata_device *dev,
1194 } 1186 }
1195 1187
1196 *p_class = class; 1188 *p_class = class;
1197 *p_id = id; 1189
1198 return 0; 1190 return 0;
1199 1191
1200 err_out: 1192 err_out:
1201 printk(KERN_WARNING "ata%u: dev %u failed to IDENTIFY (%s)\n", 1193 printk(KERN_WARNING "ata%u: dev %u failed to IDENTIFY (%s)\n",
1202 ap->id, dev->devno, reason); 1194 ap->id, dev->devno, reason);
1203 kfree(id);
1204 return rc; 1195 return rc;
1205} 1196}
1206 1197
@@ -1425,9 +1416,7 @@ static int ata_bus_probe(struct ata_port *ap)
1425 if (!ata_dev_enabled(dev)) 1416 if (!ata_dev_enabled(dev))
1426 continue; 1417 continue;
1427 1418
1428 kfree(dev->id); 1419 rc = ata_dev_read_id(ap, dev, &dev->class, 1, dev->id);
1429 dev->id = NULL;
1430 rc = ata_dev_read_id(ap, dev, &dev->class, 1, &dev->id);
1431 if (rc) 1420 if (rc)
1432 goto fail; 1421 goto fail;
1433 1422
@@ -2788,7 +2777,7 @@ int ata_dev_revalidate(struct ata_port *ap, struct ata_device *dev,
2788 int post_reset) 2777 int post_reset)
2789{ 2778{
2790 unsigned int class = dev->class; 2779 unsigned int class = dev->class;
2791 u16 *id = NULL; 2780 u16 *id = (void *)ap->sector_buf;
2792 int rc; 2781 int rc;
2793 2782
2794 if (!ata_dev_enabled(dev)) { 2783 if (!ata_dev_enabled(dev)) {
@@ -2796,8 +2785,8 @@ int ata_dev_revalidate(struct ata_port *ap, struct ata_device *dev,
2796 goto fail; 2785 goto fail;
2797 } 2786 }
2798 2787
2799 /* allocate & read ID data */ 2788 /* read ID data */
2800 rc = ata_dev_read_id(ap, dev, &class, post_reset, &id); 2789 rc = ata_dev_read_id(ap, dev, &class, post_reset, id);
2801 if (rc) 2790 if (rc)
2802 goto fail; 2791 goto fail;
2803 2792
@@ -2807,8 +2796,7 @@ int ata_dev_revalidate(struct ata_port *ap, struct ata_device *dev,
2807 goto fail; 2796 goto fail;
2808 } 2797 }
2809 2798
2810 kfree(dev->id); 2799 memcpy(dev->id, id, sizeof(id[0]) * ATA_ID_WORDS);
2811 dev->id = id;
2812 2800
2813 /* configure device according to the new ID */ 2801 /* configure device according to the new ID */
2814 rc = ata_dev_configure(ap, dev, 0); 2802 rc = ata_dev_configure(ap, dev, 0);
@@ -2818,7 +2806,6 @@ int ata_dev_revalidate(struct ata_port *ap, struct ata_device *dev,
2818 fail: 2806 fail:
2819 printk(KERN_ERR "ata%u: dev %u revalidation failed (errno=%d)\n", 2807 printk(KERN_ERR "ata%u: dev %u revalidation failed (errno=%d)\n",
2820 ap->id, dev->devno, rc); 2808 ap->id, dev->devno, rc);
2821 kfree(id);
2822 return rc; 2809 return rc;
2823} 2810}
2824 2811
@@ -4873,14 +4860,11 @@ void ata_host_set_remove(struct ata_host_set *host_set)
4873int ata_scsi_release(struct Scsi_Host *host) 4860int ata_scsi_release(struct Scsi_Host *host)
4874{ 4861{
4875 struct ata_port *ap = ata_shost_to_port(host); 4862 struct ata_port *ap = ata_shost_to_port(host);
4876 int i;
4877 4863
4878 DPRINTK("ENTER\n"); 4864 DPRINTK("ENTER\n");
4879 4865
4880 ap->ops->port_disable(ap); 4866 ap->ops->port_disable(ap);
4881 ata_host_remove(ap, 0); 4867 ata_host_remove(ap, 0);
4882 for (i = 0; i < ATA_MAX_DEVICES; i++)
4883 kfree(ap->device[i].id);
4884 4868
4885 DPRINTK("EXIT\n"); 4869 DPRINTK("EXIT\n");
4886 return 1; 4870 return 1;
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 220b9d7bfc28..0e1a3be39475 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -360,7 +360,7 @@ struct ata_device {
360 unsigned long flags; /* ATA_DFLAG_xxx */ 360 unsigned long flags; /* ATA_DFLAG_xxx */
361 unsigned int class; /* ATA_DEV_xxx */ 361 unsigned int class; /* ATA_DEV_xxx */
362 unsigned int devno; /* 0 or 1 */ 362 unsigned int devno; /* 0 or 1 */
363 u16 *id; /* IDENTIFY xxx DEVICE data */ 363 u16 id[ATA_ID_WORDS]; /* IDENTIFY xxx DEVICE data */
364 u8 pio_mode; 364 u8 pio_mode;
365 u8 dma_mode; 365 u8 dma_mode;
366 u8 xfer_mode; 366 u8 xfer_mode;
@@ -425,6 +425,8 @@ struct ata_port {
425 struct list_head eh_done_q; 425 struct list_head eh_done_q;
426 426
427 void *private_data; 427 void *private_data;
428
429 u8 sector_buf[ATA_SECT_SIZE]; /* owned by EH */
428}; 430};
429 431
430struct ata_port_operations { 432struct ata_port_operations {